WPF:使用两个DatePickers来表示日期范围

时间:2012-10-05 18:18:13

标签: wpf xaml datepicker

我有一个包含一对DateTime的viewmodel?对象 - 可以为空的DateTimes。

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");
    }
}

xmitdtFrom日期不能大于xmitdtFrom日期,xmitdtTo日期不能在xmitdtFrom日期之前,并且xmitdtTo日期和xmitdtFrom都不能在今天之后。

所以,在标记中我有这个:

<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}"
        />

这个工作正常,除非xmitdtTo为null - 在这种情况下xmitdtFrom是不受限制的,这是一个问题。

我想要的是将xmitdtFrom的DisplayDateEnd设置为xmitdtTo(如果它不为null),或设置为DateTime.Now(如果它是。)

我想知道最简洁的方法是什么。

3 个答案:

答案 0 :(得分:1)

我决定完全采用另一种方法。

我没有弄乱视图模型,而是创建了一个IfNullConverter,当它在绑定中使用时会传递绑定对象(如果它不为null),或者传递其ConversionParameter(如果它是。)

我用它来绑定from date的DisplayDateEnd - 用xmitDTTo作为绑定属性,DateTime.Now作为ConversionParameter。

完全在UI内彻底解决问题(这是一个UI问题,而不是数据问题,因此我更喜欢不会污染视图模型的解决方案)。它创建了一个通用功能,可以在其他类似情况下使用。

转换器:

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();
    }
}

绑定:

<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}}"
    />

答案 1 :(得分:0)

也许你可以尝试添加另一个可以在DisplayDateEnd中绑定的属性。像这样(未经测试):

    private DateTime? _displayDateEnd;
    public DateTime? DisplayDateEnd
    {
        get { return this._displayDateEnd; }
        set
        {
            this._displayDateEnd = value; 
            notifyPropertyChanged("DisplayDateEnd");
        }

从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"); 
        } 
    }

您更新的xaml:

<DatePicker ... DisplayDateEnd="{Binding DisplayDateEnd}"/>

答案 2 :(得分:0)

你真的需要xmitdtTo为null吗?我的意思是,当它为空时你没有得到或保存重要数据,对吗?如果是这种情况,那么我会通过将_xmitdtTo设置为今天作为默认值来规避整个问题。

private DateTime? _xmitdtTo = DateTime.Today; 

如果您需要保留数据,那么您可以更改属性,而不是今天在_xmitdtTo为空时返回。

public DateTime? xmitdtTo   
{   
    get
    {
        if (!_xmitdtTo.HasValue)
            return DateTime.Today;
        return this._xmitdtTo; 
    }  

如果确实想要保留数据的空值,那么您可以在对象上创建一个单独的属性,以分配给xmitdtTo的DisplayDateEnd:

public DateTime xmitdtDateEnd
{
    get
    {
        return _xmitdtTo ?? DateTime.Today;
    }
}

不要忘记在xmitdtTo属性赋值中添加对notifyPropertyChanged(“xmitdtDateEnd”)的调用,以便在更改xmitdtTo时更新UI。

set 
{ 
    this._xmitdtTo = value; 
    notifyPropertyChanged("xmitdtTo"); 
    notifyPropertyChanged("xmitdtDateEnd"); 
}