将 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 模型 属性 的值时,它不会在我的用户控件中更改。我想我做错了什么,但目前我不知道。
可能想到两种可能性:
- 您的 "model"(您是说视图模型?)没有实现
INotifyPropertyChanged
and/or 当 IconTypeValue
更改其值时您没有触发 PropertyChanged
.
- 您在 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
}
我有一个具有单一依赖性的简单用户控件属性(该控件是其自身的模型)
属性 不直接绑定到用户控件内的任何内容,但我需要将其值绑定到我放置我的 window (或用户控件或其他)的模型用户控制。
如果我手动设置用户控件 属性 值,属性 被正确修改,因此我可以假设用户控件中的依赖项 属性 正在工作。
如果我将值设置为 属性 将其绑定到我的 window 模型,就像这样
<lctrl:InfoIconControl Grid.Row="0" Name="InfoIconTest" IconType="{Binding Path=IconTypeValue}"/>
其中 IconTypeValue 是 window 模型的 属性,当我设置 window 模型 属性 的值时,它不会在我的用户控件中更改。我想我做错了什么,但目前我不知道。
可能想到两种可能性:
- 您的 "model"(您是说视图模型?)没有实现
INotifyPropertyChanged
and/or 当IconTypeValue
更改其值时您没有触发PropertyChanged
. - 您在 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
}