[英]How to bind custom dependecy property to control's view model?
I need to create a control with few inputs / output with lots of internal functionality. 我需要创建一个具有很少输入/输出的控件,并具有许多内部功能。 I think the best approach is to create
Dependency Properties
for interaction with other application parts and have a private
view model
with hidden functions. 我认为最好的方法是创建
Dependency Properties
以与其他应用程序部分交互,并具有隐藏功能的private
view model
。
Here is my sample: 这是我的样本:
Window 窗口
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:app="clr-namespace:WpfApplication1">
<StackPanel>
<DatePicker x:Name="DatePicker" />
<app:MyControl DateCtrl="{Binding ElementName=DatePicker, Path=SelectedDate}" />
</StackPanel>
</Window>
MyControl MyControl
<UserControl x:Class="WpfApplication1.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:app="clr-namespace:WpfApplication1">
<UserControl.DataContext>
<app:ViewModel />
</UserControl.DataContext>
<Grid>
<TextBlock Text="{Binding DateVM}" />
</Grid>
</UserControl>
Control code-behind 控制代码隐藏
using System;
using System.Windows;
namespace WpfApplication1
{
public partial class MyControl
{
public MyControl()
{
InitializeComponent();
}
public static DependencyProperty DateCtrlProperty = DependencyProperty.Register("DateCtrl", typeof(DateTime), typeof(MyControl));
public DateTime DateCtrl
{
get { return (DateTime) GetValue(DateCtrlProperty); }
set { SetValue(DateCtrlProperty, value); }
}
}
}
ViewModel 视图模型
using System;
using System.ComponentModel;
namespace WpfApplication1
{
public class ViewModel : INotifyPropertyChanged
{
private DateTime _dateVM;
public DateTime DateVM
{
get { return _dateVM; }
set
{
_dateVM = value;
OnPropertyChanged("DateVM");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I need to achieve is to propagate date
chosen in DatePicker
down to MyControl's
view model
. 我需要实现的是将
DatePicker
选择的date
传播到MyControl's
view model
。 Alternatively, is there any better pattern to use? 或者,有没有更好的模式可供使用?
What you describe is a common misconception that all views should have a view model. 您所描述的是一种常见的误解,即所有视图都应具有视图模型。 However, it is usually far simpler (and more appropriate) for
UserControl
s that are used as controls to simply use their own DependencyProperty
s. 但是,
UserControl
通常更简单(也更合适)用作控件来简单地使用自己的DependencyProperty
。
The problem with your method is that you have assigned the UserControl DataContext
internally, so it cannot be set from outside the control. 您的方法的问题是您已在内部分配了
UserControl DataContext
,因此无法从控件外部进行设置。 The solution is to not set the DataContext
internally, but instead to use a RelativeSource Binding
to access the UserControl DependencyProperty
s like this: 解决方案是不在内部设置
DataContext
,而是使用RelativeSource Binding
来访问UserControl DependencyProperty
如下所示:
<TextBlock Text="{Binding DateCtrl, RelativeSource={RelativeSource
AncestorType={x:Type YourLocalPrefix:MyControl}}}" />
If you really have to use an internal view model, then declare a DependencyProperty
of that type and data bind to it in the same way that I showed above: 如果你真的必须使用内部视图模型,那么声明该类型的
DependencyProperty
和数据绑定到它,就像我在上面显示的那样:
<TextBlock Text="{Binding YourViewModelProperty.DateVM, RelativeSource={RelativeSource
AncestorType={x:Type YourLocalPrefix:MyControl}}}" />
The DatePicker should have it's own DatePickerViewModel which defines a SelectedDate property or dependency property. DatePicker应该有自己的DatePickerViewModel,它定义了SelectedDate属性或依赖属性。 You should define the XAML of the DatePicker control to use this dedicated ViewModel.
您应该定义DatePicker控件的XAML以使用此专用ViewModel。
Then, when you use the control , you can set the binding like so: 然后,当您使用该控件时 ,您可以像这样设置绑定:
<DatePicker SelectedDate="{Binding Path=DateVM,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
Note that DateVM is not a property of the date picker, but a property on the consuming view model (or in this case, Main Window). 请注意,DateVM不是日期选择器的属性,而是消费视图模型(或在本例中为主窗口)上的属性。 When the picker is opened, it will default to the date already set in DateVM.
当选择器打开时,它将默认为DateVM中已设置的日期。
The other thing is that your picker doesn't allow any picking at the moment - it's just a text block! 另一件事是你的选择器目前不允许任何选择 - 它只是一个文本块!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.