简体   繁体   English

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

[英]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.

相关问题 如何编写自定义依赖属性和数据绑定到自定义类型? - How to write a custom dependecy property and data bind to custom type? 如何将自定义控件的依赖项属性绑定到其视图模型属性 - How to bind a dependency property for a custom control to its view models property 属性已更改的自定义控件和视图模型绑定 - Custom Control and View Model Binding with Property Changed 将属性绑定到自定义控件 - Bind a property to a custom control 如何将控件的属性绑定到另一个控件的属性? - How to bind a control's property to another control's property? 如何使用Style将子UserControl的Dependency属性绑定到宿主元素的视图模型的属性? - How to bind a child `UserControl`'s Dependency Property, using `Style`, to a property of the host element's view-model? 如何将ObservableCollection正确绑定到Custom Control属性? - How to bind properly and ObservableCollection to a Custom Control property? 如何在自定义控件的视图模型中绑定依赖项属性 - How to bind a Dependency Property in a Viewmodel of a Custom Control 将视图模型属性设置器绑定到控制方法 - Bind view-model property setter to control method 如何将数据绑定到控件的Visibility属性 - How to bind data to a control's Visibility property
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM