2012-10-05 73 views
1

我有一个viewmodel包含一对DateTime?对象 - 可为空的DateTimes。WPF:使用两个DatePickers来表示一个日期范围

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为空 - 在这种情况下xmitdtFrom是不受限制的,这是一个问题。

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

我想知道什么可能是完成这个最简洁的方法。

+0

你真的应该执行你的约会验证与'IDataErrorInfo'您的视图模型,并没有UI尝试使完成它/禁用日期范围。毕竟,我认为任何东西都不会阻止用户将日期复制/粘贴到日期框中。 – Rachel

+0

在xaml中设置DisplayDateEnd =“{x:Static sys:DateTime.Now}”会在用户在午夜截止时打开应用程序时给您一个潜在的错误,使得某人即使选择了新的一天也不可能一个有效的选择。这是一个不太可能发生的事情,这取决于你的应用程序的使用情况,但我想我会指出它,因为它加强了Rachel的观点。 –

+1

我非常强烈地感觉到,这是一个更好的UI设计,用于禁用用户不允许选择的选项,而不是允许他选择某些内容,然后在之后告诉他他错了。验证仍然是必要的,以防用户输入日期而不是选择日期,但允许无效日期在日历中处于活动状态是一个非常糟糕的主意。 –

回答

1

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

我创建了一个IfNullConverter,它在绑定中使用时会传递绑定对象,如果它不为null,或者会传递其ConversionParameter(如果是的话)。

我用它来绑定从日期的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}}" 
    /> 
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}"/> 
0

难道你真的需要xmitdtTo为空?我的意思是,当你的重要数据为空时,你没有得到或保留它,对吧?如果是这种情况,那么我会通过将_xmitdtTo设置为默认值来绕过整个问题。

private DateTime? _xmitdtTo = DateTime.Today; 

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

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

如果你真的要保留数据的NULL的含量,那么你完全可以在对象上创建一个单独的属性分配给xmitdtTo的DisplayDateEnd:

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

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

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

是的。我不仅需要它为空,我需要它默认为null。 –

+0

更新了支持您的基础属性无效的选项的答案。 –

+0

只是澄清 - 这是一个选择标准的形式。这些数据用于在SQL语句中构建where子句。如果xmitdtFrom不为null,则在where子句中添加一个“AND xmitdt>'{0}'”。用户必须能够指定xmitdt的限制,但他也必须能够不指定xmitddt的限制。 –

相关问题