将窗口模型值绑定到用户控件依赖项属性

时间:2015-07-13 16:48:06

标签: wpf data-binding dependency-properties

我有一个简单的用户控件,它具有一个依赖属性(控件是其自身的模型)

该属性不直接绑定到用户控件内的任何内容,但我需要将其值绑定到我放置用户控件的窗口模型(或用户控件或其他)。

如果我手动设置用户控件属性值,则会正确修改属性,因此我可以假设用户控件中的依赖项属性正在运行。

如果我将值设置为Property,则将其绑定到我的窗口模型,如此

<lctrl:InfoIconControl Grid.Row="0" Name="InfoIconTest" IconType="{Binding  Path=IconTypeValue}"/>

其中IconTypeValue是窗口模型的属性,当我设置窗口模型属性的值时,它不会在我的用户控件中更改。我认为我做错了什么,但目前我没有任何线索。

1 个答案:

答案 0 :(得分:1)

可能会想到两种可能性:

  1. 您的&#34;型号&#34; (你的意思是viewmodel?)没有实现INotifyPropertyChanged和/或当PropertyChanged更改其值时你没有触发IconTypeValue
  2. 您已在UserControl中执行了类似this.DataContext = this的操作,现在Binding无法正常工作,因为它正在您的控件中查找IconTypeValue属性,而不是在&中查找它#34;模型&#34;
  3. 选项1的解决方案很简单:实现界面并确保在属性更改时触发事件。

    选项2的解决方案只是删除UserControl中的任何DataContext设置,而是依赖控件的XAML中的相对绑定(RelativeSource,ElementName等)。或者,如果你要设置DataContext的东西,不要设置UserControl的一个。而是将容器的DataContext设置为UserControl。

    在您的情况下,由于您正在为UserControl使用viewmodel,因此将其用作DataContext是有意义的。但是如果你想支持绑定到UserControl的DependencyProperties,那么你必须将你的viewmodel设置为其他东西的DataContext ......例如,你的XAML中的第一个Grid。

    只需命名网格:

    <Grid x:Name="LayoutRoot">
    

    并将您的viewmodel设置为其DataContext:

    InfoIconControlModel mModel;
    public InfoIconControl()
    {
        InitializeComponent();
        mModel = new InfoIconControlModel();
        LayoutRoot.DataContext = mModel;  // this.DataContext = mModel; <-- DON'T DO THIS
    }
    

    之后,Bindings将开始工作。但是你犯了另一个典型的错误:你只是从你的财产的CLR设置者那里调用SetIcon

    public InfoIconType IconType
    {
        get
        {
            return (InfoIconType)this.GetValue(IconTypeProperty);
        }
        set
        {
            this.SetValue(IconTypeProperty, value);
            this.SetIcon();   // <-- This won't work with Binding
        }
    }
    

    相反,您还必须从DependencyPropertyChanged回调中调用它(另一方面,您已经定义了回调):

    /// <summary>
    /// Icon Type dependency Property
    /// </summary>
    public static readonly DependencyProperty IconTypeProperty = DependencyProperty.Register(
        FLD_IconType, typeof(InfoIconType), typeof(InfoIconControl), new PropertyMetadata(InfoIconType.ICPlus, IconTypePropertyChanged));
    
    
    ///<summary>
    /// 
    ///</summary>
    private static void IconTypePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        InfoIconControl ic = sender as InfoIconControl;
        ic.SetIcon();   // <-- This will work with Binding
    }