[英]Implementing two-way binding in WPF with a DateTime DependencyProperty
I've built a WPF user control that contains, among other controls, a DatePicker. 我建立了一个WPF用户控件,其中包含一个DatePicker。 My application is written with the MVVM design pattern.
我的应用程序是使用MVVM设计模式编写的。 I want to be able to insert my user control into a view and bind the user control's DatePicker's SelectedDate property to a property of DateTime on my view's ViewModel.
我希望能够将用户控件插入视图中,并将用户控件的DatePicker的SelectedDate属性绑定到视图的ViewModel上的DateTime属性。 I want the default value shown to be the value stored on my view's viewmodel, and I want changes to the date through interaction with the DatePicker to update my view's viewmodel DateTime property.
我希望显示的默认值是存储在视图的ViewModel中的值,并且希望通过与DatePicker交互来更改日期以更新视图的ViewModel DateTime属性。
I'm successfully seeing the proper bound value displayed in the DatePicker control, but when I change the date my view's viewmodel's DateTime property setter is not firing. 我成功地看到在DatePicker控件中显示了正确的绑定值,但是当我更改日期时,视图的viewmodel的DateTime属性设置器未触发。
This is what I have for my user control's code-behind: 这是我的用户控件背后的代码:
public partial class AgeDiscountUserControl : UserControl
{
public AgeDiscountUserControl()
{
InitializeComponent();
}
public DateTime DateTime
{
get { return (DateTime)GetValue(DateTimeProperty); }
set { SetValue(DateTimeProperty, value); }
}
public static readonly DependencyProperty DateTimeProperty =
DependencyProperty.Register("DateTime", typeof(DateTime), typeof(AgeDiscountUserControl));
}
And in my user control's XAML, I have: 在用户控件的XAML中,我有:
...
xmlns:my="clr-namespace:jkshay.UserControls"
...
<DatePicker Grid.Row="0" SelectedDate="{Binding DateTime, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType=my:AgeDiscountUserControl}}" DockPanel.Dock="Right"/>
...
In my view's viewmodel (which implements INotifyPropertyChanged), I've a DateTime property to which I'd like to bind my user control's DatePicker's SelectedDate property. 在我视图的viewmodel(实现INotifyPropertyChanged)中,我有一个DateTime属性,我想将用户控件的DatePicker的SelectedDate属性绑定到该属性。
...
private DateTime birthdate;
public DateTime Birthdate
{
get { return birthdate; }
set
{
if(birthdate != value)
{
birthdate = value;
NotifyPropertyChanged(() => Birthdate);
}
}
}
...
Finally, in my view's XAML, my AgeDiscountUserControl's binding is: 最后,在我的视图的XAML中,我的AgeDiscountUserControl的绑定是:
...
<uc:AgeDiscountUserControl DateTime="{Binding Birthdate}"/>
...
As stated previously, the proper value is initially displayed in the user control's DatePicker, but changes made by the DatePicker don't affect the bound property. 如前所述,正确的值最初显示在用户控件的DatePicker中,但是DatePicker所做的更改不会影响bound属性。
Am I missing something here, or do I simply have a complete misunderstanding of DependencyProperties? 我是否在这里遗漏了一些东西,还是对DependencyProperties完全误解了?
I should mention that if I insert a DatePicker in my view and bind it to my viewmodel's Birthdate property, it works as expected. 我应该提到,如果我在视图中插入DatePicker并将其绑定到我的视图模型的Birthdate属性,它将按预期工作。
As you have already figured out, the Binding
must be two-way to ensure the source is updated when the target control's value changes. 如您所知,
Binding
必须是双向的,以确保在目标控件的值更改时更新源。 But you need not do that explicitly: you may want to make two-way binding the default for your DateTime
property. 但是您不必显式地执行此操作:您可能希望将双向绑定设置为
DateTime
属性的默认值。 You can do this by specifying a flag when you register your dependency property: 您可以通过在注册依赖项属性时指定一个标志来做到这一点:
public static readonly DependencyProperty DateTimeProperty =
DependencyProperty.Register(
"DateTime",
typeof(DateTime),
typeof(AgeDiscountUserControl),
new FrameworkPropertyMetadata(
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault // <--
)
);
On Sinatr's suggestion, I added a Mode=TwoWay setting to my view's XAML, and everything now works as expected. 根据Sinatr的建议,我在视图的XAML中添加了Mode = TwoWay设置,现在一切正常。
Updated pertinent XAML is: 更新的相关XAML是:
<uc:AgeDiscountUserControl DateTime="{Binding Birthdate, Mode=TwoWay}"/>
I now see my Birthdate setter firing upon interaction with the user control. 现在,我看到与用户控件进行交互时会触发我的Birthdate setter。 Thanks for the suggestion, Sinatr.
谢谢你的建议,辛纳特尔。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.