讓我澄清一下你的理解:
是在後臺代碼一般是可以避免的,但僅僅是因爲MVVM使得它很容易綁定到視圖模型,以線了你的視覺元素與屬性和命令場景是視圖特定視圖的代碼隱藏
代碼後面的功能是完全可以接受的假設它不穿過關注的邊界。例如,我在我的應用程序中有一個對頁面進行一些可視化處理的視圖,爲此我需要視圖中有代碼。此代碼也可能與視圖模型層交互,但它不會直接引用視圖模型,因此保持我的組件鬆散耦合
如果您有需要特定方法調用的控件,則創建一個事件聚合器消息以將通知傳播到視圖是完全正確的,因爲你仍然保持視圖模型和視圖之間的關注分離(並且應用程序組件保持封裝和可測試)
示例視圖(我已經將所有事件聚合器連接起來,代碼和潛在的依賴注入東西出來的清晰度):
public class MyView : IHandle<SomeNotificationMessageType>
{
// Handler for event aggregator messages of type SomeNotificationMessageType
public void Handle(SomeNotificationMessageType message)
{
// Call a method on one of the page controls
SomePageControl.SomeMethod();
}
}
很顯然,你不會做的是這樣的視圖模型:
public class MyViewModel : IViewAware
{
public void DoSomethingThatAffectsView()
{
var view = this.GetView() as MyView;
view.SomePageControl.SomeMethod();
}
}
違反了MVVM原則,因爲你是緊密耦合MyViewModel和MyView的。
如果你想使用在卡利微它允許在同一視圖模型的多個視圖的Context
財產?上面的代碼會中斷 - 即使您檢查了View類型,您仍然會得到意大利麪代碼,例如
public class MyViewModel : IViewAware
{
public void DoSomethingThatAffectsView()
{
var myview = this.GetView() as MyView;
if(myview != null)
myview.SomePageControl.SomeMethod();
var myotherview = this.GetView() as MyOtherView;
if(myotherview != null)
myotherview.SomePageControl.SomeMethod();
// ad infinitum...
}
}
當然,這是主觀的:它可能是你的用戶控件影響視圖模型,並以複雜的方式的觀點,在這種情況下,你可能要考慮尋找架構和工作指出,用戶控件如何能更好地適合
你有什麼背景知道UC是什麼,它的方法是什麼?
謝謝你的解釋。我會用EventAggregator的想法去。我說的UC是AvalonDock,我想要做的是保存/加載佈局。在版本1中*有一個SaveLayout()方法;現在從版本2開始。0顯然必須將整個UC DockingManager傳遞給一個特殊的Serializer。 – PeterE
「爲了清晰起見,所有......依賴注入的東西都被清除了」,現在還不清楚。 :)我能想到的唯一方法是獲取Event Aggregator,在View的無參數構造函數中使用'IoC.Get()'。有沒有更好的方法來注入依賴關係,而不是直接從容器中拉對象? –
您的視圖也參與依賴注入 - 只需將其添加到構造函數即可。 – Charleh