2011-08-20 49 views
2

雖然學習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類型是輕量級結構

問:是否可以綁定到.X,同時更新綁定,只要任何沿Location.X鏈的變化的特性?是否有像「Binding prop1.prop2.prop3」這樣的「更長鏈」的通用解決方案?

回答

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該屬性發生變化。因此,虛擬機偵聽模型更改並在必要時通知:

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

THANKYOU!偶然發現你的答案,這是本頁唯一解決我的問題的答案。 <3 – rikkit

1

在我的WPF體驗中,我沒有辦法實現你所談論的內容,就像我意識到並在現在見面一樣。

當分配X時,您會跳過實際屬性。

所以你需要手動通知做綁定機制,該屬性已被改變,但如何你會找出你的例子中的屬性已被改變,如果你直接將值分配給公衆字段的結構?

問候。

+0

問題是X和Y都不會被直接修改,因爲它們屬性不是字段。所以我不能做「model.Location.X = number」。位置設置爲整體:「位置=新點()」。我開始相信這是一個關於RenderTransform的問題。 – pbalaga

2

通常,綁定中的任何屬性都會更改。但是,只有當鏈中的每個屬性都正確提升PropertyChanged時纔有效,因爲無法找出其他情況發生變化的方法。

對於這個工作,你需要要麼執行INotifyPropertyChangedPoint,提高PropertyChangedXY變化,或者你需要提高事件Location當這種情況發生。

+0

事實上,無法僅更改X或Y,因爲Location是模型上的ValueType屬性。所以唯一的辦法就是做:model.Location = new Point(...)。因此,整個位置發生變化並通知。現在我想問題是'TranslateTransform',它不是一個FrameworkElement(沒有DataContext)。 WPF輸出一個錯誤:「無法找到目標元素的控制FrameworkElement或FrameworkContentElement」。但我不知道什麼是解決方法。特別是綁定最初起作用。 – pbalaga

+0

只能更改'X'。 'model.Location.X = 42'應該可以工作(除非'Point'是隻讀的,它真的應該是 - 可變結構是壞事)。它何時輸出該錯誤? – svick

+0

當'Location'是* ValueType屬性*時,你不能這樣做。此作業的'model.Location'部分將生成本地Point副本。 'model.Location.X = 42'會改變該副本上​​的X.這甚至不會編譯。 – pbalaga