2013-10-28 108 views
3

我父視圖模型包含幾個子視圖模型,它看起來像父視圖模型遺棄兒童視圖模型的屬性

public MainViewModel:ObservableObject 
{ 
    public MainViewModel(){//initalize everything}; 

    private SomeViewModel childvm1; 
    private AnotherViewModel childvm2; 


     public SomeViewModel Childvm1 
      { 
       get 
       { 
        return childvm1; 
       } 
       set 
       { 
        SetField(ref childvm1, value, "Childvm1"); 
       } 
      } 

    public AnotherViewModel Childvm2 
      { 
       get 
       { 
        return childvm2; 
       } 
       set 
       { 
        SetField(ref childvm2, value, "Childvm2"); 
       } 
      } 

    //when this changes i want to notify childvm2 and call a function in it 
    public SomeModel SelectedValueofChildvm1 
      { 
       get 
       { 
        return Childvm1.SelectedValue; 
       } 
      } 
} 

我怎麼能調用一個函數在childvm2SelectedValueofChildvm1變化?

+0

如果沒有'set','SelectedValueofChildvm1'如何改變? –

+0

設置在childvm1中,我是否也必須在此處公開它? – FPGA

+0

您是否需要對價值的變化做出反應,還是隻是試圖使其可以綁定? – CodingGorilla

回答

4

你要訂閱子視圖模型的PropertyChangedEvent,就像這樣:

public SomeViewModel Childvm1 
{ 
    get 
    { 
     return childvm1; 
    } 
    set 
    { 
     if (childvm1 != null) childvm1.PropertyChanged -= OnChildvm1PropertyChanged; 
     SetField(ref childvm1, value, "Childvm1"); 
     if (childvm1 != null) childvm1.PropertyChanged += OnChildvm1PropertyChanged; 
    } 
} 

private coid OnChildvm1PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    // now update Childvm2 
} 

但要小心:

  • 你可能要同時更新childvm2在Childvm2二傳手
  • 您需要確保childvm1實例的活動時間不超過MianViewModel實例,或者在將MainViewModel返回到垃圾回收器之前將Childvm1設置爲null。
+1

如果您希望子視圖模型發生變化,這很好,如果不是,那麼我的方法就簡單多了。 =) – CodingGorilla

+1

顯然,OP期望它們改變,因爲包含了Childvm1屬性的公共setter。另外,我不知道爲什麼你的解決方案比這更簡單?您不會退訂該事件,因此您的代碼少了一行,這是事實。但是在這個解決方案中,訂閱和取消訂閱是很好的對稱,並且它們屬於它的屬性,這很好,而且不那麼脆弱。 –

+1

這並不是一種批評,我的觀點是,如果他不希望它發生變化,那麼只需在構造函數中連接處理程序並且完成就簡單多了。我們沒有看到'SetField'的作用,所以它完全有可能處理屬性更改通知,但不允許更改特定字段(如子視圖模型)。 – CodingGorilla

1

這個最簡單的方法是使用INotifyPropertyChanged接口來偵聽屬性更改通知。

public MainViewModel:ObservableObject 
{ 
    public MainViewModel(){ 
     //initalize everything 
     Childvm1.PropertyChanged += (s,e) { 
      if(e.PropertyName == "SelectedValue") { 
       // Do what you want 
      }   
     }; 
    }; 

}