绑定到子属性,并在链中的任何属性发生更改时进行更新
本文关键字:属性 更新 任何 绑定 | 更新日期: 2023-09-27 18:06:26
在学习MVVM时,我为我的一个视图模型创建了一个DataTemplate
:
<DataTemplate DataType="{x:Type task:NodeDefinitionVM}">
<Ellipse Width="4" Height="4" Fill="Red" >
<Ellipse.RenderTransform>
<TranslateTransform X="{Binding Location.X, Mode=TwoWay}"
Y="{Binding Location.Y, Mode=TwoWay}" />
</Ellipse.RenderTransform>
</Ellipse>
</DataTemplate>
简化视图模型类:
class NodeDefinitionVM : (...)
{
public Point Location
{
get { return model.Location; }
set { model.Location = value; }
}
(...)
}
在我的情况下,模型实现INotifyPropertyChanged,因为我需要在视图中反映模型的所有更改(注意XAML中的Mode=TwoWay
)。
问题:转换偏移量(X, Y)的初始值设置,当'Location'属性更改时,我得到通知。然而,没有通知。X已经改变了,因为我绑定到Location。X时,转换不会更新(除了第一次),因为它需要Location。X变更通知。Point
类型为轻量级结构体。
问题:是否可以绑定到. x,同时在位置的任何属性上更新绑定?X链变化?像Binding prop1.prop2.prop3
这样的"长链"是否有一般的解决方案?
一般来说,当链中的任何属性发生变化时,绑定都应该更新。但只有当链中的每个属性都正确地引发PropertyChanged
时,这才有效,因为没有办法知道其他地方发生了什么变化。
要做到这一点,您需要在Point
上实现INotifyPropertyChanged
,并在X
或Y
发生变化时引发PropertyChanged
,或者您需要在发生这种情况时引发Location
的事件。
奇怪的是,直接绑定到TranslateTransform的X或Y属性将不能很好地工作,尽管它们是DependencyProperties。以下修改使其工作:
<DataTemplate DataType="{x:Type task:NodeDefinitionVM}">
<Ellipse x:Name="ellipse" Width="4" Height="4" Fill="Red"
RenderTransform="{Binding TranslateMatrix}">
</Ellipse>
</DataTemplate>
我需要在我的ViewModel中创建一个新的' TranslateMatrix
'属性:
public TranslateTransform TranslateMatrix
{
get
{
var tt = new TranslateTransform(model.Location.X, model.Location.Y);
return tt;
}
}
最后,VM需要在每次Location
属性更改时发布TranslateMatrix
属性更改的通知。因此,VM监听模型更改并在必要时发出通知:
void NodeDefinitionVM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "Location")
NotifyPropertyChanged(() => TranslateMatrix);
}
在我的WPF经验中,没有办法实现你所说的。
当分配X
时,您跳过了实际属性。
所以你需要手动通知绑定机制属性被改变了,但是在你的例子中,如果你直接给结构体的公共字段赋值你怎么知道属性被改变了呢?
问候。