2011-08-08 68 views
2

Im新的MVVM,並有小問題。我有兩個用戶控件:父和子(有視圖,視圖模型,模型類)。並且需要將一些屬性從父母傳遞給孩子。現在香港專業教育學院管理它通過寫這樣的代碼:將屬性從一個「視圖」傳遞到MVVM中的其他視圖的視圖模型

public static readonly DependencyProperty CallbackActionProperty = 
       DependencyProperty.Register("CallbackAction", typeof (Action), 
     typeof (ChildView), new PropertyMetadata(default(Action))); 

public Action CallbackAction 
{ 
    get { return (Action) GetValue(CallbackActionProperty); } 
    set 
    { 
    SetValue(CallbackActionProperty, value); 
    ((ChildViewModel)this.DataContext).CallbackAction = value; // Change ViewModel property too 
    } 
} 

這是依賴屬性在ChildView和自己的一套我還設置了ViewModel的財產。之後,我從ParentView訪問該依賴項屬性,並設置CallbackAction - >,它在Child's ViewModel中設置CallbackAction
代碼:

this.Loaded += (sender, args) => childUc.CallbackAction = ((ParentViewModel) this.DataContext).RefreshStatuses; 

childUc是用戶控件,位於親和由ChildView表示。 代碼很難看,所以我希望在不破壞模式方面看到更好的做法。 謝謝。

+0

問題是什麼? –

+0

@Mario Vernari,讓事情試圖描述的正確方法是什麼? – 0x49D1

回答

3

是的 - 這段代碼很醜。事實上,我正在努力研究它究竟做了什麼!

MVVM模式的主要租戶之一是ViewModel應該是單元可測試的,應該可以在沒有視圖的情況下執行它。面對這樣的問題時,只考慮視圖模型而忽視視圖。

您的ParentViewModel具有對ChildViewModel的引用,您可以通過讓ParentViewModel在創建ChildViewModel時提供對其自身的引用來使其成爲雙向關係。這意味着從ChildViewModel你可以在ParentViewModel上執行任何公共方法。

考慮到這一點,你應該能夠解決你的問題!

(同樣,你不應該在你的依賴項屬性的getter或setter添加邏輯,該代碼可能會或可能不會根據您的依賴屬性值是如何設置調用。)

+0

嗯,很好的建議!當然,我可以創建Parent的接口並將該接口類型的引用傳遞給Child(我可以爲該子節點創建許多「不同的」父級用戶控件)。謝謝,我會嘗試。關於思考ViewModel的建議是我認爲最好的。當然,它必須沒有查看。 – 0x49D1

+0

是的,將一個接口傳遞給只有它應該能夠調用的方法的ChildViewModel聽起來像是個好主意。 – ColinE

+1

孩子們永遠不應該知道誰是他們的父母,但父母是。如果你想從任何後代向上「溝通」,你應該使用命令。這允許在沒有任何耦合的情況下向血統交換數據。 –

1

不要在setter或getter中編寫任何邏輯,因爲它被框架以其他方式調用,而不是直接通過set/get訪問器。這是一個必須的規則。

另外串

((ChildViewModel)this.DataContext).CallbackAction = value; 

引入當前查看和底層視圖模型類型之間並列耦合,這不是一個MVVM原理。

在View依賴性的情況下,您應該考慮使用XAML中的綁定來傳遞屬性,否則ParentViewModel應該通過構造函數注入一個ChildViewModel。所以他們應該被設計來表示ParentViewModel有一個孩子...

相關問題