2010-07-16 4 views
0

빌드중인 응용 프로그램에서 하나 이상의 다른보기 모델에서 동작을 트리거해야하는보기 (보기 모델 지원)에서 사용자가 무언가를 수행 할 수 있습니다. 이러한 다른 vms 각각은 첫 번째 v/vm 쌍에서 수행 된 작업을 거부 (a.k.a. 취소) 할 수있는 기능이 필요합니다.Veto 옵션이있는 느슨하게 결합 된 내부보기 모델 알림

예 :

  1. 사용자가 계정 목록보기에 표시 DataGrid 컨트롤에 계정을 클릭합니다. DataGrid 이벤트 핸들러는 클릭을 트래핑하고 VM에 알려줍니다. Vm은 제안 된 변경 사항의 다른 vms에 알립니다.
  2. 사용자가 다른보기의 레코드에 대해 저장하지 않은 편집을했기 때문에 다른 vm은 제안 된 선택된 계정 변경이 거부되었음을 첫 번째 vm에 알립니다.
  3. 계정 목록 vm에서이 거부를 받으면 선택한 계정을 그대로 유지하도록 DataGrid에 지시합니다. 거부를받지 않으면 계정 목록 vm을 통해 DataGrid에서 선택한 항목 변경이 발생합니다.

비슷한 시나리오는 사용자가 응용 프로그램 종료를 시작하는 경우입니다. 관심있는 가상 머신은 종료가 제안되었고 종료를 취소 할 수있는 옵션이 있음을 알 수있는 방법이 필요합니다.

뷰 모델은 느슨하게 결합되어야하므로 이들 간의 직접 이벤트 구독은 바람직하지 않습니다.

이 인트라 뷰 모델 통신을 어떻게 구현 하시겠습니까?

계정 변경 이벤트를 "브로드 캐스트"하는 것이 현명한 방법일까요? 이벤트 인수 객체에는 bool Canceled 속성이 포함됩니다. 변경을 취소하려는 구독 VM은 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를 만들었습니다.