Wpf 日期选择器不';除非焦点更改为另一个控件,否则不能更新视图模型

Wpf 日期选择器不';除非焦点更改为另一个控件,否则不能更新视图模型,wpf,datepicker,Wpf,Datepicker,如何使DatePicker控件更新视图模型而不丢失焦点 我希望能够运行这个示例,键入12/9/11作为日期,单击窗口的关闭按钮,并获得Debug.Assert传递。如果我在关闭窗口之前将选项卡切换到文本框,则可以正常工作 使用系统; 使用系统组件模型; 使用系统诊断; 命名空间日期选择器测试 { 公共部分类主窗口 { 公共主窗口() { 初始化组件(); DataContext=新的ViewModel(); } 私有void主窗口关闭(对象发送方,取消事件参数) { var dataCont

如何使DatePicker控件更新视图模型而不丢失焦点

我希望能够运行这个示例,键入12/9/11作为日期,单击窗口的关闭按钮,并获得Debug.Assert传递。如果我在关闭窗口之前将选项卡切换到文本框,则可以正常工作


使用系统;
使用系统组件模型;
使用系统诊断;
命名空间日期选择器测试
{
公共部分类主窗口
{
公共主窗口()
{
初始化组件();
DataContext=新的ViewModel();
}
私有void主窗口关闭(对象发送方,取消事件参数)
{
var dataContext=dataContext作为ViewModel;
Assert(dataContext.SelectedDate==newDateTime(2011,12,9));
}
}
公共类视图模型
{
公共日期时间SelectedDate{get;set;}
}
}

尝试将
更新资源记录器
更改为
属性更改
,例如

<DatePicker Name="TheDate" 
            SelectedDate="{Binding Path=SelectedDate
                 , UpdateSourceTrigger=PropertyChanged
                 , Mode=TwoWay}" />

尝试将
更新资源记录器
更改为
属性更改
,例如

<DatePicker Name="TheDate" 
            SelectedDate="{Binding Path=SelectedDate
                 , UpdateSourceTrigger=PropertyChanged
                 , Mode=TwoWay}" />
试试这个:

public class CustomDatePicker : DatePicker
{
    protected DatePickerTextBox _datePickerTextBox;

    public static readonly new DependencyProperty SelectedDateProperty =
        DependencyProperty.Register(nameof(SelectedDate), typeof(DateTime?), typeof(CustomDatePicker), 
            new FrameworkPropertyMetadata(null, SelectedDateChanged) { BindsTwoWayByDefault = true });

    private static new void SelectedDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((CustomDatePicker)d).SelectedDate = (DateTime?)e.NewValue;
    }

    public new DateTime? SelectedDate
    {
        get { return (DateTime?)GetValue(SelectedDateProperty); }
        set
        {
            if (base.SelectedDate != value) base.SelectedDate = value;
            if (this.SelectedDate != value) SetValue(SelectedDateProperty, value);
        }
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        _datePickerTextBox = this.Template.FindName("PART_TextBox", this) as DatePickerTextBox;
        if (_datePickerTextBox != null)
            _datePickerTextBox.TextChanged += dptb_TextChanged;
    }

    private void dptb_TextChanged(object sender, TextChangedEventArgs e)
    {
        int index = _datePickerTextBox.SelectionStart;
        string text = _datePickerTextBox.Text;

        DateTime dt;
        if (DateTime.TryParse(_datePickerTextBox.Text, Thread.CurrentThread.CurrentCulture,
            System.Globalization.DateTimeStyles.None, out dt))
            this.SelectedDate = dt;
        else
            this.SelectedDate = null;

        _datePickerTextBox.Text = text;
        _datePickerTextBox.SelectionStart = index;
    }
}
这是我发现的改进版本。当用户键入时,它会更新所选日期。

尝试以下操作:

public class CustomDatePicker : DatePicker
{
    protected DatePickerTextBox _datePickerTextBox;

    public static readonly new DependencyProperty SelectedDateProperty =
        DependencyProperty.Register(nameof(SelectedDate), typeof(DateTime?), typeof(CustomDatePicker), 
            new FrameworkPropertyMetadata(null, SelectedDateChanged) { BindsTwoWayByDefault = true });

    private static new void SelectedDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((CustomDatePicker)d).SelectedDate = (DateTime?)e.NewValue;
    }

    public new DateTime? SelectedDate
    {
        get { return (DateTime?)GetValue(SelectedDateProperty); }
        set
        {
            if (base.SelectedDate != value) base.SelectedDate = value;
            if (this.SelectedDate != value) SetValue(SelectedDateProperty, value);
        }
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        _datePickerTextBox = this.Template.FindName("PART_TextBox", this) as DatePickerTextBox;
        if (_datePickerTextBox != null)
            _datePickerTextBox.TextChanged += dptb_TextChanged;
    }

    private void dptb_TextChanged(object sender, TextChangedEventArgs e)
    {
        int index = _datePickerTextBox.SelectionStart;
        string text = _datePickerTextBox.Text;

        DateTime dt;
        if (DateTime.TryParse(_datePickerTextBox.Text, Thread.CurrentThread.CurrentCulture,
            System.Globalization.DateTimeStyles.None, out dt))
            this.SelectedDate = dt;
        else
            this.SelectedDate = null;

        _datePickerTextBox.Text = text;
        _datePickerTextBox.SelectionStart = index;
    }
}

这是我发现的改进版本。当用户键入时,它会更新所选日期。

我更改了示例以使用您的建议,但它不起作用。我认为UpdateSourceTrigger默认为PropertyChanged,Mode默认为TwoWay.Comment by(拒绝编辑):可以,谢谢。实际上,在这种情况下需要做的只是:
绑定到文本将导致一些日期格式,如dd.mm.yyyy。无法正确解析我更改了示例以使用您的建议,但它不起作用。我认为UpdateSourceTrigger默认为PropertyChanged,Mode默认为TwoWay.Comment by(拒绝编辑):可以,谢谢。实际上,在这种情况下需要做的只是:
绑定到文本将导致一些日期格式,如dd.mm.yyyy。不被正确解析可能重复的可能重复的可能重复的感谢这一点,工程像一个魅力!谢谢你这么做,真有魅力!