C# 如何将自定义依赖属性绑定到控件';s视图模型?
我需要创建一个具有少量输入/输出和大量内部功能的控件。我认为最好的方法是创建C# 如何将自定义依赖属性绑定到控件';s视图模型?,c#,wpf,dependency-properties,C#,Wpf,Dependency Properties,我需要创建一个具有少量输入/输出和大量内部功能的控件。我认为最好的方法是创建依赖属性,以便与其他应用程序部件交互,并使用带有隐藏函数的私有视图模型 这是我的样本: 窗口 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx
依赖属性
,以便与其他应用程序部件交互,并使用带有隐藏函数的私有视图模型
这是我的样本:
窗口
<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>
视图模型
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));
}
}
}
我需要实现的是将
DatePicker
中选择的date
传播到MyControl的
视图模型
。或者,有没有更好的模式可以使用?您所描述的是一个常见的误解,即所有视图都应该有一个视图模型。但是,对于用作控件的UserControl
s,只使用它们自己的dependencProperty
s通常要简单得多(也更合适)
您的方法的问题是您在内部分配了UserControl-DataContext
,因此无法从控件外部进行设置。解决方案不是在内部设置DataContext
,而是使用relativesourcebinding
访问UserControl dependencProperty
s,如下所示:
<TextBlock Text="{Binding DateCtrl, RelativeSource={RelativeSource
AncestorType={x:Type YourLocalPrefix:MyControl}}}" />
DatePicker应该有自己的DatePickerViewModel,它定义SelectedDate属性或dependency属性。您应该定义DatePicker控件的XAML以使用此专用的ViewModel 然后,当您使用该控件时,可以按如下方式设置绑定:
<DatePicker SelectedDate="{Binding Path=DateVM,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
请注意,DateVM不是日期选择器的属性,而是消费视图模型(或者在本例中是主窗口)上的属性。当选择器打开时,它将默认为DateVM中已设置的日期
另一件事是,你的选择器目前不允许任何拾取-它只是一个文本块 示例中的
DatePicker
表示外部世界,它只知道DateCtrl
属性,不知道有一些内部视图模型具有DateVM
。TextBlock
仅用于可视化当前示例unset中的内部属性DateVM
。这将起作用,我可能会这样做,但我担心它会像我以前的WinForms
应用程序一样,在控件本身上产生大量代码。另一个缺点是我无法单独测试表示逻辑。然后使用第二个示例,将视图模型作为依赖属性提供。或者,只需将此UserControl
中的数据直接绑定到父UserControl
或窗口的视图模型即可。
<TextBlock Text="{Binding DateCtrl, RelativeSource={RelativeSource
AncestorType={x:Type YourLocalPrefix:MyControl}}}" />
<TextBlock Text="{Binding YourViewModelProperty.DateVM, RelativeSource={RelativeSource
AncestorType={x:Type YourLocalPrefix:MyControl}}}" />
<DatePicker SelectedDate="{Binding Path=DateVM,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />