2010-07-16 100 views
0

在我構建的應用程序中,用戶可以在一個視圖(由視圖模型支持)中執行某些操作,該視圖應在一個或多個其他視圖模型中觸發操作。這些其他vms中的每一個都需要否決(a.k.a.取消)在第一v/vm對中執行的動作。鬆散耦合的視圖內模型通知w/Veto選項

實施例:

  1. 用戶點擊在由帳戶列表視圖中顯示的數據網格控制的帳戶。 DataGrid事件處理程序捕獲點擊並告訴vm。 Vm通知其他提議變更的vms。
  2. 由於用戶對其他視圖中的記錄進行了未保存的編輯,因此其他vm會告訴第一個虛擬機,提議的所選帳戶更改將被拒絕。
  3. 當帳戶列表vm收到此拒絕時,它會通知DataGrid將所選帳戶保持原樣。如果沒有收到拒絕,賬戶列表vm將允許DataGrid選擇項目改變發生。

類似的情況是當用戶啓動應用程序關閉時。有興趣的vms需要一種方法來知道關閉建議並可以選擇取消關閉。

視圖模型應該鬆散耦合,因此它們之間的直接事件訂閱是不可取的。

你會如何建議實施這種視圖內模型的溝通?

會使用事件聚合器來「廣播」帳戶更改事件是一個明智的做法嗎?事件參數對象將包含一個bool Canceled屬性。訂閱虛擬機想要取消更改將設置Canceled = true

謝謝

回答

1

我覺得你的最後一段提出一個很好的解決方案。

使用MVVM Light Toolkit,我會使用帶有回調的消息來發送消息,並允許任意數量的用戶使用取消來回叫。

public class AccountSelectedMessage : NotificationMessageAction<bool> 
{ 
    public AccountSelectedMessage(Account selectedAccount, Action<bool> callback) : base("AccountSelectedWithCancelCallback", callback) 
    { 
     SelectedAccount = selectedAccount; 
    } 
    public AccountSelectedMessage(object sender, Account selectedAccount, Action<bool> callback) : base(sender, "AccountSelectedWithCancelCallback", callback) 
    { 
     SelectedAccount = selectedAccount; 
    } 
    public AccountSelectedMessage(object sender, object target, Account selectedAccount, Action<bool> callback) : base(sender, target, "AccountSelectedWithCancelCallback", callback) 
    { 
     SelectedAccount = selectedAccount; 
    } 

    public Account SelectedAccount { get; private set; } 
} 

public class AccountListViewModel : ViewModelBase 
{ 
    public RelayCommand<Account> AccountSelectedCommand = new RelayCommand<Account>(AccountSelectedCommandExecute); 

    private void AccountSelectedCommandExecute(Account selectedAccount) 
    { 
     MessengerInstance.Send(new AccountSelectedMessage(this, AccountSelectionCanceled)); 
    } 

    private void AccountSelectionCanceled(bool canceled) 
    { 
     if (canceled) 
     { 
      // cancel logic here 
     } 
    } 
} 

public class SomeOtherViewModel : ViewModelBase 
{ 
    public SomeOtherViewModel() 
    { 
     MessengerInstance.Register<AccountSelectedMessage>(this, AccountSelectedMessageReceived); 
    } 

    private void AccountSelectedMessageReceived(AccountSelectedMessage msg) 
    { 
     bool someReasonToCancel = true; 
     msg.Execute(someReasonToCancel); 
    } 
} 

正如你所看到的,這個過程將需要異步的,考慮到你不知道如何郵件的多個收件人可以取消,否則他們將需要多長時間才能作出反應。

1

EventAggregator是要走的路。我們使用了棱鏡中的一個。但是我們並沒有把所有的棱鏡都拿走。只是與EventAggregator相關的類。我們確實爲GUI參考不可用的服務層組件創建了一個DomainEvent。