2013-10-31 91 views
2

我正在使用Caliburn.Micro編寫ViewModel-first MVVM應用程序 我的視圖包含第三方UserControl,它實現了我想要/需要從關聯的ViewModel調用的方法。我如何做到這一點,同時仍然支持MVVM原則?從Caliburn.Micro的ViewModel中調用UserControl方法

存在一個老thread這裏那麼,類似的問題被問更具體的上下文。如果有人能夠充實那裏提出的方法,我將不勝感激。

方法的一個建議,查看可以訂閱的IEventAggregator消息。但是,我不需要使用文件後面的代碼來做到這一點嗎? (我認爲這是一個很大的不,不以MVVM)

關於方法有兩個,我不知道該怎麼做。關於方法三,這就是我先嚐試的,但不知何故,我沒有完全實現它。

回答

5

讓我澄清一下你的理解:

是在後臺代碼一般是可以避免的,但僅僅是因爲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是什麼,它的方法是什麼?

+0

謝謝你的解釋。我會用EventAggregator的想法去。我說的UC是AvalonDock,我想要做的是保存/加載佈局。在版本1中*有一個SaveLayout()方法;現在從版本2開始。0顯然必須將整個UC DockingManager傳遞給一個特殊的Serializer。 – PeterE

+0

「爲了清晰起見,所有......依賴注入的東西都被清除了」,現在還不清楚。 :)我能想到的唯一方法是獲取Event Aggregator,在View的無參數構造函數中使用'IoC.Get ()'。有沒有更好的方法來注入依賴關係,而不是直接從容器中拉對象? –

+0

您的視圖也參與依賴注入 - 只需將其添加到構造函數即可。 – Charleh

相關問題