仅绑定日期和仅时间
Posted
技术标签:
【中文标题】仅绑定日期和仅时间【英文标题】:Binding Date Only and Time Only 【发布时间】:2017-06-16 19:00:10 【问题描述】:我有 2 个控件:
DatePicker:仅用于日期 带有 TimeMask 的文本框:仅限时间
它们都链接到同一个属性DateTime EffectiveDate
但问题是当我更改 DatePicker 上的日期时,它会将 TimeTextBox 中的时间更改回 12:00。
我理解它的原因,但有什么最佳解决方案可以让这些单独工作但绑定到同一个属性?
我试图获取当前时间并在 set 属性中构建一个新日期,但总是以溢出错误结束。
【问题讨论】:
为什么没有两个属性 EffectiveDate 和 EffectiveTime,它们都在模型中使用相同的支持字段。 嗯,好的,我会回到那个 - 但那里也有溢出错误 【参考方案1】:您可以使用价值转换器来保持价值
public class DateConverter : IValueConverter
private DateTime timePickerDate;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
timePickerDate = ((DateTime)(value));
return value;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
if (value == null) return timePickerDate;
var datePickerDate = ((DateTime)(value));
// compare relevant parts manually
if (datePickerDate.Hour != timePickerDate.Hour
|| datePickerDate.Minute != timePickerDate.Minute
|| datePickerDate.Second != timePickerDate.Second)
// correct the date picker value
var result = new DateTime(datePickerDate.Year,
datePickerDate.Month,
datePickerDate.Day,
timePickerDate.Hour,
timePickerDate.Minute,
timePickerDate.Second);
// return, because this event handler will be executed a second time
return result;
return datePickerDate;
并让有问题的两个控件绑定到一个属性,但让日期选择器使用转换器不覆盖时间。
<Grid Margin="10,5" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<sdk:DatePicker Grid.Column="0" TabIndex="1" Padding="0" SelectedDate="Binding EffectiveDate, Mode=TwoWay, Converter=StaticResource DateConverter" SelectedDateFormat="Short"/>
<toolkit:TimePicker Grid.Column="1" Value="Binding EffectiveDate, Mode=TwoWay" Margin="0" Padding="0" HorizontalAlignment="Left" TabIndex="2" />
</Grid>
【讨论】:
正是我需要的,甚至不需要摆弄 objects 属性。谢谢一百万。 好的,发现一个问题。假设我选择了 21/01/2017,时间是 12:00。在我更改时间的那一刻,日期跳回到今天 (31/01/2017)。我是否还需要一个转换器来保持日期不变? 没有。您是否在该属性上更改了正确的通知属性?我会快速新建一个项目,看看能否重现。 @user1702369 按描述工作。当更新的时间和日期仍然存在多次更改时,我通过选择器更改了日期。 我当时正在使用带有 Mask 的扩展 TextBox。你用的是什么时间选择器【参考方案2】:你可以这样做:
private DateTime _effectiveDate;
...
public DateTime DateOfEffectiveDate
get return _effectiveDate;
set
_effectiveDate = new DateTime(value.Year, value.Month, value.Day, _effectiveDate.Hour, _effectiveDate.Minute, _effectiveDate.Second);
public DateTime TimeOfEffectiveDate
get return _effectiveDate;
set
_effectiveDate = new DateTime(_effectiveDate.Year, _effectiveDate.Month, _effectiveDate.Day, value.Hour, value.Minute, value.Second);
【讨论】:
【参考方案3】:内置的 DatePicker 控件只选择一个没有任何特定时间的日期,所以我担心尝试在 TextBox 中显示所选日期的时间是没有意义的。每次选择新日期时,DatePicker 都会有效地清除时间部分。这就是控件的工作原理。
因此,您应该将 DatePicker 和 TextBox 绑定到两个不同的源属性,分别是 DateTime?
和 TimeSpan
。
另一种选择是使用另一个选择日期和时间的控件,例如:http://wpftoolkit.codeplex.com/wikipage?title=DateTimePicker
【讨论】:
【参考方案4】:捕捉dateTimePicker1_ValueChanged
事件,然后结合date
和time
部分设置binded field value
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
DateTime dt = dateTimePicker1.Value;
int hour = Convert.ToInt32(textBox1.Text.Split(':')[0]);
int minute = Convert.ToInt32(textBox1.Text.Split(':')[1]);
bindedfield = new DateTime(dt.Year, dt.Month, dt.Day, hour, minute, 0);
【讨论】:
以上是关于仅绑定日期和仅时间的主要内容,如果未能解决你的问题,请参考以下文章
如何仅使用@DateTimeFormat 将日期@ConfigurationProperties 与时间绑定?
SQL Server:如何在总行数和仅包含数据的行数之间得到差异
日历绑定 SelectedDate 和 DisplayDate:灰色日期