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

Bind window model value to User Control Dependency Property

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

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

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

如果我将值设置为 属性 将其绑定到我的 window 模型,就像这样

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

其中 IconTypeValue 是 window 模型的 属性,当我设置 window 模型 属性 的值时,它不会在我的用户控件中更改。我想我做错了什么,但目前我不知道。

可能想到两种可能性:

  1. 您的 "model"(您是说视图模型?)没有实现 INotifyPropertyChanged and/or 当 IconTypeValue 更改其值时您没有触发 PropertyChanged .
  2. 您在 UserControl 中做了类似 this.DataContext = this 的操作,现在绑定不起作用,因为它正在您的控件中寻找 IconTypeValue 属性,而不是寻找它在 "model".

选项 1 的解决方案很简单:实现接口并确保在 属性 更改时触发事件。

选项 2 的解决方案是简单地删除 UserControl 中 DataContext 的任何设置,而是依赖于控件 XAML 中的相对绑定(RelativeSource、ElementName 等)。或者,如果您要设置某物的 DataContext,请不要设置 UserControl 的。相反,在 UserControl 中设置容器的 DataContext。

在您的情况下,由于您正在为 UserControl 使用视图模型,因此将其用作 DataContext 是有意义的。但是如果你想支持绑定到你的 UserControl 的 DependencyProperties,那么你将不得不将你的视图模型设置为其他东西的 DataContext ...例如,你的 XAML.

中的第一个 Grid

只需命名网格:

<Grid x:Name="LayoutRoot">

并将您的视图模型设置为其 DataContext:

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

之后,绑定将开始工作。但是你犯了另一个典型的错误:你只是从你的财产的 CLR setter 调用 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
}