如何让DatePicker控件更新视图模型而不会失去焦点?
我希望能够运行此示例,键入日期的12/9/11,单击窗口的关闭按钮并调试Debug.Assert。如果我在关闭窗口之前切换到文本框,它可以正常工作。
<Window x:Class="DatePickerTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Closing="MainWindow_OnClosing">
<StackPanel>
<DatePicker Name="TheDate" SelectedDate="{Binding Path=SelectedDate}" />
<TextBox/>
</StackPanel>
</Window>
using System;
using System.ComponentModel;
using System.Diagnostics;
namespace DatePickerTest
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
private void MainWindow_OnClosing(object sender, CancelEventArgs e)
{
var dataContext = DataContext as ViewModel;
Debug.Assert(dataContext.SelectedDate == new DateTime(2011, 12, 9));
}
}
public class ViewModel
{
public DateTime SelectedDate { get; set; }
}
}
答案 0 :(得分:11)
尝试将UpdateSourceTrigger
更改为PropertyChanged
,例如
<DatePicker Name="TheDate"
SelectedDate="{Binding Path=SelectedDate
, UpdateSourceTrigger=PropertyChanged
, Mode=TwoWay}" />
<强>更新强>
好吧,好像这是一个known issue DatePicker
。您可以改为绑定到Text
属性,并设置TargetNullValue
:
<DatePicker
Name="TheDate"
Text="{Binding Path=SelectedDate
, Mode=TwoWay
, UpdateSourceTrigger=PropertyChanged
, ValidatesOnDataErrors=True
, TargetNullValue=''}"
/>
答案 1 :(得分:2)
试试这个:
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;
}
}
它是我发现here的改进版本。它会在用户输入时更新SelectedDate
。