Привязка к подчиненному свойству и обновление, если какое-либо свойство в цепочке изменилось - PullRequest
2 голосов
/ 21 августа 2011

Во время изучения 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 (уведомление Mode=TwoWay в XAML).

Проблема: Установлены начальные значения смещений преобразования (X, Y), и я получаю уведомления при изменении свойства Location . Однако нет уведомления о том, что .X изменился, и, поскольку я привязан к Location.X, преобразование не обновляется (за исключением первого раза), поскольку оно ожидает Location.X уведомление об изменении. Тип Point - это легкий struct .

Вопрос: Возможно ли привязать к .X при обновлении привязки всякий раз, когда изменяется любое из свойств вдоль Location.X цепочки? Есть ли общее решение для «более длинной цепи» типа Binding prop1.prop2.prop3?

Ответы [ 3 ]

2 голосов
/ 21 августа 2011

Как правило, привязка должна обновляться при изменении какого-либо свойства в цепочке. Но это работает только тогда, когда каждое свойство в цепочке вызывает PropertyChanged должным образом, потому что нет способа выяснить, что что-то изменилось иначе.

Чтобы это работало, вам нужно либо реализовать INotifyPropertyChanged на Point и повысить PropertyChanged при изменении X или Y, либо вам нужно вызвать событие на Location, когда это произойдет .

2 голосов
/ 21 августа 2011

Как ни странно, привязка напрямую к X или Y свойствам TranslateTransform не будет работать хорошо, хотя это DependencyProperties.Следующие изменения заставили его работать:

<DataTemplate DataType="{x:Type task:NodeDefinitionVM}">
    <Ellipse x:Name="ellipse" Width="4" Height="4" Fill="Red" 
             RenderTransform="{Binding TranslateMatrix}">
    </Ellipse>
</DataTemplate>

Мне нужно было создать новое свойство 'TranslateMatrix' в моей ViewModel:

    public TranslateTransform TranslateMatrix
    {
        get
        {
            var tt = new TranslateTransform(model.Location.X, model.Location.Y);
            return tt;
        }
    }

Наконец, виртуальная машина должна опубликовать уведомления оTranslateMatrix свойство меняется каждый раз Location свойство изменяется.Поэтому виртуальная машина прослушивает изменения модели и при необходимости уведомляет:

    void NodeDefinitionVM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Location")
            NotifyPropertyChanged(() => TranslateMatrix);
    }
1 голос
/ 21 августа 2011

Нет способа достичь того, о чем вы говорите, насколько я знаю и до сих пор встречался в моем опыте WPF.

При назначении X вы перепрыгиваете через фактическое свойство.

Так что вам нужно вручную уведомить механизм связывания, что свойство было изменено, но как вы узнаете, что это свойство было изменено в вашем примере, если вы будете напрямую назначать значение общедоступному полю из структуры?

С уважением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...