簡體   English   中英

否決選項的松散耦合的視圖內模型通知

[英]Loosely Coupled Intra-View Model Notifications w/Veto Option

在我正在構建的應用程序中,用戶可能會在一個視圖(由視圖模型支持)中執行某些操作,該操作應觸發一個或多個其他視圖模型中的動作。 這些其他VM均需要具有否決(也稱為取消)在第一個v / vm對中執行的操作的能力。

例:

  1. 用戶單擊帳戶列表視圖顯示的DataGrid控件中的帳戶。 DataGrid事件處理程序將捕獲陷阱並告知vm。 Vm通知其他VM建議的更改。
  2. 由於用戶對另一個視圖中的記錄進行了未保存的編輯,因此其他虛擬機告訴第一個虛擬機建議的所選帳戶更改被拒絕。
  3. 當帳戶列表vm收到拒絕消息時,它告訴DataGrid保持所選帳戶集不變。 如果沒有收到拒絕,帳戶列表vm將允許發生DataGrid所選項目的更改。

類似的情況是用戶啟動應用程序關閉時。 感興趣的虛擬機需要一種方法來知道建議關閉,並可以選擇取消關閉。

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

您如何建議實現這種視圖內模型通信?

使用事件匯總器“廣播”帳戶更改事件是否明智? 事件參數對象將包含bool Canceled屬性。 想要取消更改的訂閱虛擬機將設置Canceled = true

謝謝,

我認為您的最后一段提出了一個好的解決方案。

使用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);
    }
}

如您所見,此過程將需要異步進行,並考慮到您不知道有多少收件人可以取消郵件,或者他們需要花費多長時間進行響應。

EventAggregator是必經之路。 我們使用了Prism的那一款。 但是,我們並沒有全力以赴。 只是與EventAggregator相關的類。 我們確實為沒有GUI引用的服務層程序集創建了一個DomainEvent。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM