Слабосвязанные уведомления модели с внутренним обзором и опция вето - PullRequest
0 голосов
/ 16 июля 2010

В приложении, которое я создаю, пользователь может выполнить что-то в одном представлении (поддерживаемое моделью представления), что должно вызвать действие в одной или нескольких других моделях представления. Каждому из этих других vms нужна возможность наложить вето (например, отменить) действие, выполненное в первой паре v / vm.

Пример:

  1. Пользователь нажимает на учетную запись в элементе управления DataGrid, отображаемом в представлении списка учетных записей. Обработчик событий DataGrid перехватывает щелчок и сообщает vm. Vm уведомляет другие VMS о предлагаемом изменении.
  2. Поскольку пользователь внес несохраненные изменения в запись в другом другом представлении, другой vm сообщает сначала vm, что предложенное изменение выбранной учетной записи отклонено.
  3. Когда список учетных записей vm получает это отклонение, он сообщает DataGrid о том, чтобы выбранная учетная запись оставалась неизменной. Если бы отклонение не было получено, список учетных записей vm позволил бы изменениям выбранного элемента DataGrid.

Аналогичный сценарий будет, когда пользователь инициирует завершение работы приложения. Заинтересованным vms нужен способ узнать, что предлагается отключение, и иметь возможность отменить отключение.

Модели представлений должны быть слабо связаны, поэтому прямая подписка на события между ними нежелательна.

Как бы вы предложили реализовать эту модель связи внутри вида?

Будет ли разумным подходом использовать агрегатор событий для «трансляции» события смены аккаунта? Объект аргумента события будет содержать свойство bool Canceled. Подписывающийся виртуальный сервер, который хочет отменить изменение, установит Canceled = true.

Спасибо,
Бен

Ответы [ 2 ]

1 голос
/ 17 июля 2010

EventAggregator это путь.Мы использовали один из Призма.Но мы не взяли всю призму.только классы, связанные с EventAggregator.Мы создали DomainEvent для сборок сервисных уровней, где ссылки на GUI недоступны.

1 голос
/ 16 июля 2010

Я думаю, что ваш последний параграф предлагает хорошее решение.

Используя 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);
    }
}

Как видите, этот процесс должен быть асинхронным и учитывать, что вы не знаете, сколько получателей сообщения могут отменить или как долго онипотребуется, чтобы ответить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...