WPF Toolkit Extender TimePicker绑定仅获取时间问题排查
WPF Toolkit TimePicker绑定String属性仍带日期的问题分析与解决
嘿,这个问题我之前帮同事排查过,其实根源很好找!WPF Toolkit的TimePicker控件的Value属性本质是DateTime类型——你在XAML里设置的Format和FormatString只是用来控制UI上的显示样式,当它绑定到ViewModel的String属性时,默认会调用DateTime的默认ToString()方法,所以才会带出默认的日期部分(比如你看到的"1/19/2018 12:00:31 AM")。
下面给你两种靠谱的解决方法:
方法1:使用值转换器(IValueConverter)统一格式
写一个自定义的转换器,专门处理DateTime和目标字符串格式的双向转换,这样就能完全控制绑定的数值格式了。
步骤1:实现转换器代码
using System; using System.Globalization; using System.Windows.Data; public class TimeToStringConverter : IValueConverter { // 把DateTime转成指定格式的字符串 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is DateTime timeValue) { return timeValue.ToString("hh:mm tt", culture); } return string.Empty; } // 把字符串转回DateTime(反向绑定用) public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value is string timeStr && DateTime.TryParseExact(timeStr, "hh:mm tt", culture, DateTimeStyles.None, out DateTime parsedTime)) { // 这里用当天日期作为日期部分,你也可以根据需求调整成固定日期 return new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, parsedTime.Hour, parsedTime.Minute, parsedTime.Second); } // 转换失败时返回默认值,也可以抛出异常或者处理成你需要的逻辑 return DateTime.MinValue; } }
步骤2:在XAML中引用并使用转换器
首先在窗口/用户控件的资源里声明转换器:
<Window.Resources> <!-- 这里的local是你转换器所在的命名空间,记得替换成自己的 --> <local:TimeToStringConverter x:Key="TimeToStringConverter"/> </Window.Resources>
然后修改TimePicker的绑定,加上转换器:
<xctk:TimePicker Margin="106,178,170,256" Format="Custom" FormatString="hh:mm tt" TimeInterval="00:15" Value="{Binding Time, Mode=TwoWay, Converter={StaticResource TimeToStringConverter}}" />
方法2:修改ViewModel属性类型为DateTime(更推荐)
其实TimePicker的设计就是用来处理DateTime类型的,如果你能调整ViewModel的属性类型,会更贴合控件的设计逻辑:
ViewModel代码修改
private DateTime _time; public DateTime Time { get { return _time; } set { SetProperty(ref _time, value, () => Time); } } // 如果你需要在其他地方用字符串格式的时间,可以加一个只读属性 public string TimeDisplay => _time.ToString("hh:mm tt");
这样修改后,TimePicker的Format设置会正常控制UI显示,ViewModel里存储的是完整的DateTime,但如果你只需要时间部分,直接取Time.Hour、Time.Minute就行,或者用上面的TimeDisplay属性获取格式化后的字符串。
额外注意事项
- 确保你的程序Culture设置正确,比如如果需要显示英文的AM/PM,要确保Culture是en-US之类的;如果是中文环境,"tt"会显示“上午/下午”。
- 用转换器的时候,记得在ConvertBack里做好错误处理,避免输入无效时间导致绑定出错。
内容的提问来源于stack exchange,提问作者Progolfer79
相关产品推荐
相关产品推荐

