1

我定义了一个简单的 DatePicker:

<DatePicker SelectedDate="{Binding SomeDate}"/>

而且我想防止用户在某些情况下清除该值。

这是我到目前为止得到的:

public DateTime? SomeDate
{
    get { return someDate; }
    set
    {
        if (someDate != value)
        {
            if (value == null && someCondition)
                TellTheUserHeCannotClearTheField();
            else
                someDate = value;
            NotifyPropertyChanged(() => SomeDate);
        }
    }
}

虽然这可以防止基础字段被更新,但 DatePicker 仍然显示一个空值(即"<Enter text here>"),并在每次用户通过它进行选项卡时再次尝试将属性更新为 null。

如何强制 DatePicker 显示当前未更改的值?


根据Doc的评论回答,让我概括一下。

使用下拉菜单时,可以以这种方式拒绝日期更改(例如,如果我想限制范围)。

但是,如果您使用键盘,您输入的任何内容都会保留在那里,并且 DatePicker 会在每次失去焦点时尝试提交它。

4

3 回答 3

1

我找到了一个相当不错的解决方案。

问题是该SelectedDate属性已正确更新,但该Text属性(即显示的内容)现在不同步。

因此,我写了一个助手来保持同步:

public class SelectedDateSyncBehavior
{
    public static readonly DependencyProperty SyncTextProperty =
        DependencyProperty.RegisterAttached("SyncText", typeof(bool), 
            typeof(SelectedDateSyncBehavior), new PropertyMetadata(false, 
                                                  HandleSyncTextChanged));

    static void HandleSyncTextChanged(DependencyObject d, 
                                      DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
            ((DatePicker)d).LostFocus += SyncText;
        else
            ((DatePicker)d).LostFocus -= SyncText;
    }

    static void SyncText(object sender, RoutedEventArgs e)
    {
        var picker = (DatePicker)sender;
        if (picker.SelectedDate != null)
            picker.Text = picker.SelectedDate.Value.ToShortDateString();
    }

    public static void SetSyncText(DatePicker element, bool value)
    {
        element.SetValue(SyncTextProperty, value);
    }

    public static bool GetSyncText(DatePicker element)
    {
        return (bool)element.GetValue(SyncTextProperty);
    }
}

现在我要做的就是:

<DatePicker SelectedDate="{Binding SomeDate}" 
            myns:SelectedDateSyncBehavior.SyncText="True"/>
于 2013-01-22T20:53:26.877 回答
0

我似乎无法重现它。

我这样设置属性TestDate

private DateTime? _testDate = DateTime.Now;

public DateTime? TestDate {
  get { return _testDate; }
  set {
    if (value < DateTime.Now)
      System.Windows.MessageBox.Show("BAD!");
    else
      _testDate = value;
    OnPropertyChanged("TestDate");
  }
}

像这样的 DatePicker:

<DatePicker SelectedDate="{Binding TestDate}" />

这是我的行为:

  • 选择“坏”日期(1 月 16 日)

在此处输入图像描述

  • 坏消息

在此处输入图像描述

  • 值与原始值不变

在此处输入图像描述

  • 选择好的日期(作品)

在此处输入图像描述

这个例子和你想做的一样,对吧?(我的 MVVM 实现有点不同。)

于 2013-01-22T18:18:42.727 回答
-1

标准 WPFDatePicker没有类似IsReadOnly. 阻止用户输入的唯一方法是禁用它:

<DatePicker SelectedDate="{Binding SomeDate}" IsEnabled="{Binding AllowEditSomeDate}"/>

视图模型:

public bool AllowEditSomeDate {get;set;} //Do not forget INotifyPropertyChanged
于 2013-01-22T15:36:55.127 回答