【问题标题】:Validation for DateTime property in viewmodel在视图模型中验证 DateTime 属性
【发布时间】:2013-02-07 11:43:58
【问题描述】:

我的视图模型类中有一个 DateTime 属性(例如 DateVal),视图中有一个 DatePicker 控件。

    <DatePicker         Grid.Column="1"
                        Width="100"
                        Height="30"
                        SelectedDate="{Binding DateVal,ValidatesOnDataErrors=True}"/>

问题是,如果用户删除显示在 Datepicker 控件文本框中的日期,DateVal 属性不会改变它的值。如何跟踪用户已删除日期选择器文本框中显示的日期? 问候, 阿尼尔班

日期选择器控件如下所示 现在,如果用户只是删除日期选择器文本框中显示的日期,则控件如下所示 此时 DateVal 的值与以前相同。 仅当用户单击日历图标时 Date 才被分配一个 null 值。 当用户将文本框设为空时,如何跟踪更改?

ViewModel 代码

public DateTime? DateVal
    {
        get
        {
            return this.dateVal;
        }
        set
        {
            this.dateVal = value;
            this.OnPropertyChanged("DateVal");
        }
    }

xml 代码

<DatePicker Name="datePickerDateVal"
                        Grid.Column="1"
                        Width="100"
                        Height="30"
                        SelectedDate="{Binding DateVal,ValidatesOnDataErrors=True}"
                        Text="{Binding DateVal,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}"                          />

我希望当用户清除 Date Picker 文本框时必须调用 DateVal 的 setter 属性

【问题讨论】:

    标签: wpf validation data-binding mvvm datepicker


    【解决方案1】:

    不幸的是,DatePicker 的文本框设置为仅在失去焦点时更新其绑定源。好消息是,您可以通过DatePickerControlTemplate 进入该过程:

    XAML:

    <DatePicker SelectedDate="{Binding DateVal}" x:Name="__picker" />
    

    以及背后的代码:

    DateTime? _dateVal = DateTime.Today;
    
    public Nullable<DateTime> DateVal
    {
        get { return _dateVal; }
        set
        {
            if (_dateVal == value)
                return;
    
            _dateVal = value;
            OnPropertyChanged("DateVal");
        }
    }
    
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        DatePickerTextBox pickerTextBox = __picker.Template.FindName("PART_TextBox", __picker) as DatePickerTextBox;
        if (pickerTextBox == null)
            return;
    
        pickerTextBox.TextChanged += new TextChangedEventHandler(pickerTextBox_TextChanged);
    }
    
    void pickerTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        DatePickerTextBox tb = sender as DatePickerTextBox;
    
        if (tb == null)
            return;
    
        if (string.IsNullOrEmpty(tb.Text))
        {
            __picker.SelectedDate = null;
        }
    }
    

    我只是摆弄它,我的猜测是您没有得到更频繁更新的原因是文本和选定日期属性之间的循环关系。确保我们得到 null DateTimes 的更新应该没问题。

    编辑

    更新了事件处理程序以更新选择器SelectedDate 属性,而不是视图模型中的属性。这样,您可以将 hack 完全保留在视图中,同时保持与视图模型无关。

    【讨论】:

    • 我实际上正在使用可为空的 DateTime 属性。它没有帮助。
    • 能否把相关代码贴在后面/VM代码?我使用我在答案中发布的简单 sn-p 代码运行与您相同的 XAML,并且 DateVal 属性更新清晰可见。
    • 抱歉让你挂了。在找出(可能的)解决方案之前,我不得不进行一些研究。
    • 我遵循 MVVM 设计模式。因此,从视图后面的代码中设置 DateVal(ViewModel 类的属性)是不正确的。
    • 好吧,一点点改动就能满足你所​​有的 MVVM 需求。
    猜你喜欢
    • 1970-01-01
    • 2011-04-04
    • 2020-01-19
    • 2012-01-24
    • 2011-08-05
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    相关资源
    最近更新 更多