WPF:使用两个 DatePicker 来表示日期范围
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12751876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF: Using two DatePickers to represent a date range
提问by Jeff Dege
I have a viewmodel that contains a pair of DateTime? objects - nullable DateTimes.
我有一个包含一对 DateTime 的视图模型?对象 - 可为空的日期时间。
private DateTime? _xmitdtFrom;
public DateTime? xmitdtFrom
{
get { return this._xmitdtFrom; }
set
{
this._xmitdtFrom = value;
notifyPropertyChanged("xmitdtFrom");
}
}
private DateTime? _xmitdtTo;
public DateTime? xmitdtTo
{
get { return this._xmitdtTo; }
set
{
this._xmitdtTo = value;
notifyPropertyChanged("xmitdtTo");
}
}
The xmitdtFrom date cannot be greater than the xmitdtFrom date, the xmitdtTo date cannot be before the xmitdtFrom date, and neither the xmitdtTo date not the xmitdtFrom can be after today.
xmitdtFrom 日期不能大于 xmitdtFrom 日期,xmitdtTo 日期不能在 xmitdtFrom 日期之前,xmitdtTo 日期和 xmitdtFrom 日期都不能在今天之后。
So, in the markup I have this:
所以,在标记中我有这个:
<Label Grid.Row="1" Grid.Column="1">
From:
</Label>
<DatePicker Grid.Row="1" Grid.Column="2"
SelectedDate="{Binding xmitdtFrom, Mode=TwoWay}"
DisplayDateEnd="{Binding xmitdtTo}"
/>
<Label Grid.Row="2" Grid.Column="1">
Through:
</Label>
<DatePicker Grid.Row="2" Grid.Column="2"
SelectedDate="{Binding xmitdtTo, Mode=TwoWay}"
DisplayDateStart="{Binding xmitdtFrom}"
DisplayDateEnd="{x:Static sys:DateTime.Now}"
/>
And this works fine, unless xmitdtTo is null - in which case xmitdtFrom is unrestricted, which is a problem.
这工作正常,除非 xmitdtTo 为空 - 在这种情况下 xmitdtFrom 不受限制,这是一个问题。
What I want is to set DisplayDateEnd for the xmitdtFrom to the xmitdtTo, if it's not null, or to DateTime.Now, if it is.
我想要的是将 xmitdtFrom 的 DisplayDateEnd 设置为 xmitdtTo(如果它不为空)或 DateTime.Now(如果是)。
And I'm wondering what might be the cleanest way of accomplishing this.
我想知道什么可能是实现这一目标的最干净的方式。
采纳答案by Jeff Dege
I decided to go with another approach entirely.
我决定完全采用另一种方法。
Instead of messing about with the viewmodel, I created an IfNullConverter, that when used in a binding would pass the bound object, if it was not null, or would pass its ConversionParameter, if it was.
我没有搞乱视图模型,而是创建了一个 IfNullConverter,它在绑定中使用时将传递绑定对象(如果它不为 null),或者将传递其 ConversionParameter(如果是)。
And I used that in binding the from date's DisplayDateEnd - with xmitDTTo as the bound property, and DateTime.Now as the ConversionParameter.
我用它来绑定起始日期的 DisplayDateEnd - 使用 xmitDTTo 作为绑定属性,并将 DateTime.Now 作为 ConversionParameter。
Solves the problem cleanly, entirely within the UI (and this is a UI problem, not a data problem, so I'd prefer a solution that doesn't pollute the viewmodel). And it creates a general purpose functionality, that will be available to use in other similar circumstances.
完全在 UI 中干净地解决了问题(这是 UI 问题,而不是数据问题,所以我更喜欢不污染视图模型的解决方案)。它创建了一个通用功能,可用于其他类似情况。
The converter:
转换器:
public class IfNullConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return parameter;
else
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
The binding:
绑定:
<DatePicker Grid.Row="1" Grid.Column="2"
SelectedDate="{Binding Path=xmitdtFrom, Mode=TwoWay}"
DisplayDateEnd="{Binding xmitdtThrough, Converter={StaticResource ifNullConverter}, ConverterParameter={x:Static sys:DateTime.Now}}"
/>
回答by Big Daddy
Maybe you can try adding another property that you can bind to in DisplayDateEnd. Something like this (untested):
也许您可以尝试添加另一个可以在 DisplayDateEnd 中绑定的属性。像这样的东西(未经测试):
private DateTime? _displayDateEnd;
public DateTime? DisplayDateEnd
{
get { return this._displayDateEnd; }
set
{
this._displayDateEnd = value;
notifyPropertyChanged("DisplayDateEnd");
}
Set the new property's value from xmidtTo:
从 xmidtTo 设置新属性的值:
private DateTime? _xmitdtTo;
public DateTime? xmitdtTo
{
get { return this._xmitdtTo; }
set
{
this._xmitdtTo = value;
if (_xmitdtTo == null)
DisplayDateEnd = _xmitdtTo;
else
DisplayDateEnd = DateTime.Now();
notifyPropertyChanged("DisplayDateEnd");
notifyPropertyChanged("xmitdtTo");
}
}
Your updated xaml:
您更新的 xaml:
<DatePicker ... DisplayDateEnd="{Binding DisplayDateEnd}"/>
回答by Jacob Proffitt
Do you ever really need xmitdtTo to be null? I mean, you're not getting or preserving important data when it's null, right? If that's the case, then I'd circumvent the whole problem by setting _xmitdtTo to today as a default.
你真的需要 xmitdtTo 为空吗?我的意思是,当重要数据为空时,您不会获取或保留重要数据,对吗?如果是这种情况,那么我会通过将 _xmitdtTo 设置为今天作为默认值来规避整个问题。
private DateTime? _xmitdtTo = DateTime.Today;
If you need to preserve the data, then you can alter the property, instead, to return today when _xmitdtTo is null.
如果您需要保留数据,那么您可以更改该属性,当 _xmitdtTo 为空时返回今天。
public DateTime? xmitdtTo
{
get
{
if (!_xmitdtTo.HasValue)
return DateTime.Today;
return this._xmitdtTo;
}
If you reallywant to preserve the nullness of your data, then you could create a separate property altogether on your object to assign to the DisplayDateEnd of xmitdtTo:
如果你真的想保留你的数据的空值,那么你可以在你的对象上创建一个单独的属性来分配给 xmitdtTo 的 DisplayDateEnd:
public DateTime xmitdtDateEnd
{
get
{
return _xmitdtTo ?? DateTime.Today;
}
}
Don't forget to add a call to notifyPropertyChanged("xmitdtDateEnd") in the xmitdtTo property assignment so it'll update the UI when you change xmitdtTo.
不要忘记在 xmitdtTo 属性赋值中添加对 notifyPropertyChanged("xmitdtDateEnd") 的调用,以便在您更改 xmitdtTo 时更新 UI。
set
{
this._xmitdtTo = value;
notifyPropertyChanged("xmitdtTo");
notifyPropertyChanged("xmitdtDateEnd");
}

