繁体   English   中英

如何将自定义依赖属性绑定到控件的视图模型?

[英]How to bind custom dependecy property to control's view model?

我需要创建一个具有很少输入/输出的控件,并具有许多内部功能。 我认为最好的方法是创建Dependency Properties以与其他应用程序部分交互,并具有隐藏功能的private view model

这是我的样本:

窗口

<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

<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>

控制代码隐藏

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); }
    }
}
}

视图模型

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's view model 或者,有没有更好的模式可供使用?

您所描述的是一种常见的误解,即所有视图都应具有视图模型。 但是, UserControl通常更简单(也更合适)用作控件来简单地使用自己的DependencyProperty

您的方法的问题是您已在内部分配了UserControl DataContext ,因此无法从控件外部进行设置。 解决方案是不在内部设置DataContext ,而是使用RelativeSource Binding来访问UserControl DependencyProperty如下所示:

<TextBlock Text="{Binding DateCtrl, RelativeSource={RelativeSource 
    AncestorType={x:Type YourLocalPrefix:MyControl}}}" />

如果你真的必须使用内部视图模型,那么声明该类型的DependencyProperty和数据绑定到它,就像我在上面显示的那样:

<TextBlock Text="{Binding YourViewModelProperty.DateVM, RelativeSource={RelativeSource 
    AncestorType={x:Type YourLocalPrefix:MyControl}}}" />

DatePicker应该有自己的DatePickerViewModel,它定义了SelectedDate属性或依赖属性。 您应该定义DatePicker控件的XAML以使用此专用ViewModel。

然后,当您使用该控件时 ,您可以像这样设置绑定:

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

请注意,DateVM不是日期选择器的属性,而是消费视图模型(或在本例中为主窗口)上的属性。 当选择器打开时,它将默认为DateVM中已设置的日期。

另一件事是你的选择器目前不允许任何选择 - 它只是一个文本块!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM