2012-11-28 34 views
2

Caliburn.Micro畫面轉變我有一個Caliburn.Micro殼(即,空的XAML視圖到包含其它視圖)由導體視圖模型呈現。從那裏,我通過打開屏幕經由導體

ActivateItem(...) 

通常從新顯示的對話框,用戶可以執行一些操作,然後單擊按鈕(OK取消構建 ....),這應該每個都轉換到另一個屏幕(在shell中)。

public MyDialog : Screen 
{ 
    public void Ok() 
    { 
     // TODO: Somehow tell the conductor or called of this class about this action. 
    } 
} 

什麼是實現這些類型的對話動作/消息屏幕轉換的好方法?

  • 簡單.NET事件是可能的 - 這不是一個壞主意嗎?
  • CM IEventAggregator也應該通過改變視圖
  • 從殼指揮檢查視圖模型結果一旦它已經通過TryClose()關閉工作 - 應該是可能的,只是不知道如何做到這一點釐米。
  • 引用殼該屏幕上的導體實例(通過IoC或直接) - 這似乎是強耦合。

能否請您提供建議。

+0

找到一個很好的文章描述瞭如何使用'IEventAggregator':http://www.mindscapehq.com/blog/index.php/2012/02/01/caliburn -micro-part-4-the-event-aggregator/ – Wernight

回答

3

我的首選方法是使用EventAggregator來促進VM之間的消息傳遞。

當你有多個偵聽特定類型的事件的窗口時(例如Visual Studio風格的界面帶有多個工具窗口,可能顯示上下文敏感的屬性),這個工作特別好,但是這聽起來有點矯枉過正。當然,優點仍然是虛擬機和缺少事件之間的良好鬆散耦合(這是一件好事!)

聽起來好像你想要一個模式對話框來彈出並顯示一個選項,然後激活另一個屏幕一次第一個回來了。

您可以將事件處理程序附加到子VM中的Deactivated事件,該子事件將在項目停用時觸發。它還會在參數中傳遞一個布爾值來通知停用的項目是否已關閉 - 您可以檢查並激活導體中的相應屏幕。

例如

this.Deactivated += new EventHandler<DeactivationEventArgs>(WorkspaceViewModel_Deactivated); 

void WorkspaceViewModel_Deactivated(object sender, DeactivationEventArgs e) 
{ 
    if(e.WasClosed) // raise some event 
} 

然後傳遞事件到售票員,我不會真的去爲這個事件的路線。這樣可以單向連接虛擬機,因此它可能不是最靈活的解決方案

另一種方法是通過事件聚合器觸發消息,以告知指揮官需要在子虛擬機關閉時打開不同的窗口。可以使用相同的方法,但它的退耦

this.Deactivated += new EventHandler<DeactivationEventArgs>(WorkspaceViewModel_Deactivated); 

void WorkspaceViewModel_Deactivated(object sender, DeactivationEventArgs e) 
{ 
    if(e.WasClosed) MainConductor.EventAggregator.Publish(new ActivateWindowMessage(typeof(SomeVM)); 
} 
+0

你對我的目標是正確的。一旦找到如何創建EventAggregator,我會在我的「Ok」方法中嘗試EventAggregator。另外我覺得這個虛擬機依賴於Shell/Main Conductor是很奇怪的。應該只是相反的方式。 – Wernight

+0

就是說,虛擬機應該自己照顧自己,並且虛擬機應該注意顯示適當的視圖,孩子虛擬機應該通過消息傳遞但是以間接的方式指定父虛擬機應該做什麼,以免兩者耦合。我可能寫了一個令人困惑的帖子! – Charleh

+0

不,不,這很好,我更關注哪些解決方案通常更好,爲什麼,如果可能的話如何實施。我已經使用了IEvAgg的構造函數注入的方式,使它們不緊密耦合。 – Wernight