2014-04-18 186 views
0

我正在構建我的第一個WPF和MVVM應用程序。我有3次(用3周對應的ViewModels)如何在ViewModels之間進行通信?

1)主窗口(窗口)

2)ViewClients(用戶控件)

3)ViewModClient(用戶控件)

在客戶端ViewModel我有一個屬性SelectedClient跟蹤視圖中的DataGrid上選定的客戶端。在這個視圖中,我也有一個與在MainWindow ViewModel中定義的ICommand相關的按鈕。 我這個結合解決它:

Command="{Binding Path=DataContext.CreateViewsCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter={x:Type local:ViewModClient} 

我用CommandParameter告訴主窗口視圖模型樣的看法,以建立和保持從知識觀隔離視圖模型其中。這很好。

現在的問題:

在ModClient視圖模型我需要加載客戶端的數據。那麼我如何將這與Clients View中的SelectedClient相關聯,同時保持MVVM模式呢? (我只能使用一個CommandParameter並且已經使用它)

+0

也許使用某種形式的EventAggregator?您可以從ViewClients VM引發事件並在ViewModClient VM中訂閱它。 –

+0

謝謝你的回答。你能給我一些示例代碼嗎?也許你可以發佈它像一個建議的答案。 – ericpap

+0

查看MVVM Light Toolkit,它具有內置的消息傳遞支持https://mvvmlight.codeplex.com/ – reggaeguitar

回答

1

Caliburn.Micro例如,有一個建於IEventAggregator,它允許你創建Eventmanagers可以是蘇也訂閱。如果您使用多個ViewModels訂閱此特定EventAggegrator,則可以定義可從已訂閱此EventAggregator的所有ViewModel發佈和接收的消息。

下只有很短的執行和顯示,的ViewModels之間的通信多麼容易,如果你使用一個框架像Caliburn.Micro:

class ViewModel1 : PropertyChangedBase 
{ 
    private IEventAggregator _Event; 
    public ViewModel1(IEventAggregator events) 
    { 
     _Event = events; 
     _Events.Publish(new TestEvent(5)); 
    } 
} 

class ViewModel2 : PropertyChangedBase, IHandle<TestEvent> 
{ 
    private IEventAggregator _Events; 
    public ViewModel2(IEventAggregator events) 
    { 
     _Events = events; 
     _Events.Subscribe(this); 
    } 

    public void Handle(TestEvent message) 
    { 
     // do something with the incoming message 
    } 
} 

class TestEvent 
{ 
    public int foo { get; set; } 
    public TestEvent(int someint) 
    { 
     foo = someint; 
    } 
} 

它應該是自我解釋的。但是,如果您有任何問題,請告訴我,我會詳細介紹。

1

通常這是通過使用消息傳遞完成的。

所有MVVM框架有一個消息總線,允許虛擬機間的通信,以便只是得到一個很好的框架和任務會得到如此簡單(Simple MVVM Toolkit):

源VM:

SendMessage(MessageTokens.SomeToken, new NotificationEventArgs<string> 
      (MessageTokens.SomeToken, "MyMessage")); 

接收VM:

RegisterToReceiveMessages<string>(MessageTokens.SomeToken, OnMessageReceived); 

private void OnMessageReceived(object sender, NotificationEventArgs<string> e) 
{ 
    // Code to execute upon message reception. 
} 
+0

感謝您的回答,但現在我試圖遠離外部框架。我不想在我的應用程序中添加另一個變量和問題的來源。任何其他選項? – ericpap

+1

如果您不想使用第三方MVVM框架,有幾個選項。 1)實現你自己的Messenger類。 2)使用事件,並讓虛擬機訂閱彼此的事件。這就是說; MVVM不僅僅是一個實現INotifyPropertyChanged的類。這是一個由多個部分組成的設計模式,使者是其中的一部分。使用第三方框架比試圖推出自己的產品更簡單。 – BTownTKD

+0

嗨@BTownTKD,謝謝你的回答。我是所有這些技術的新手,我很難展現mvvm模式。 Rigth現在,我設法解決導航問題,並且在沒有外部框架的情況下加載了多個視圖,事實上,我沒有看到引入新的sintaxis和我不真正需要的對象的觀點。我嘗試使用Caliburn.Micro,但似乎是「重新開始」來理解他的sintaxis。如果我不使用框架,還有什麼我錯過了?我會嘗試使用事件並訂閱viewModels。謝謝! – ericpap

相關問題