绑定到子属性并更新链中的任何属性是否已更改

时间:2011-08-20 21:48:02

标签: c# xaml binding

在学习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,因为我需要对View中反映的模型进行所有更改(在XAML中注意Mode=TwoWay)。

问题:设置了转换偏移(X,Y)的初始值,当“位置”属性发生变化时,我会收到通知。但是没有通知 .X 已更改,并且由于我绑定到Location.X,因此转换不会更新(第一次除外),因为它期望Location.X更改通知。 Point类型是轻量级结构

问题:当 Location.X 链中的任何属性发生变化时,是否可以绑定到.X,同时更新绑定?是否有Binding prop1.prop2.prop3这样的“较长链”的通用解决方案?

3 个答案:

答案 0 :(得分:2)

通常,绑定应在链中的任何属性更改时更新。但这只适用于链中的每个属性正确引发PropertyChanged,因为没有办法弄清楚某些事情会发生变化。

为了实现这一点,您需要在INotifyPropertyChanged上实施Point并在PropertyChangedX更改时提升Y,或者您需要当发生这种情况时,提升Location的事件。

答案 1 :(得分:2)

奇怪的是,直接绑定到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需要发布TranslateMatrix属性每次Location属性更改时发生更改的通知。因此,VM会监听模型更改并在必要时通知:

    void NodeDefinitionVM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Location")
            NotifyPropertyChanged(() => TranslateMatrix);
    }

答案 2 :(得分:1)

在我的WPF体验中,没有办法达到你所说的,就像我所知道的那样,直到现在还没有。

在分配X时,您会跳过实际属性。

因此,您需要手动通知do Binding机制,该属性已更改,但如果您直接将值分配给公共 field ,您将如何确定该示例中的属性已更改结构?

问候。