Получение просмотра модели для запуска модального диалога - PullRequest
0 голосов
/ 14 июля 2011

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

МЕТОД 1) В настоящее время я использую событие в модели lookupview, которую пользовательский элемент управления знает для прослушивания.

МЕТОД 2) Я попытался сгенерировать исключение проверки в установщике свойства на lookupviewmodel, что свойство текста элемента управления lookup также связано. Затем я подключил ErrorEvent к пользовательскому элементу управления поиском. Но кажется, что если пользователь «исправляет» значение из диалога, в то время как в этом событии, первоначальное значение остается неизменным. И что еще хуже, даже после того, как я вызываю Validation.ClearInvalid, еще один ErrorEvent все еще срабатывает, что каким-то образом добавляет ошибку обратно. Таким образом, все работает здесь в том смысле, что все модели представления имеют правильные данные, просто кажется, что текстовое поле игнорирует, что свойство связанного текста изменилось в базовом источнике данных, когда он находится внутри ErrorEvent. Похоже, я не могу исправить ошибку во время обработки этой ошибки?

Другая проблема в методе 2 заключается в том, что Validation.ClearInvalid не удаляет красную границу ошибки. Мне пришлось вручную очистить ErrorTemplate тоже. Это верно?

Я хотел бы найти способ использовать естественную обработку ошибок в элементе управления, чтобы он вызывал модальное диалоговое окно.

Ответы [ 2 ]

1 голос
/ 14 июля 2011

Это не то, для чего вы используете события.События существуют для облегчения развязки: объект, вызывающий событие, не должен знать или не заботиться о том, что делают объект (ы), слушающие его.Вы ожидаете, что событие сможет изменить значение свойства из установщика свойства - или, что еще хуже, ваш обработчик событий вызывает тот самый установщик свойства, который вызывает событие, которое он обрабатывает, а это значит, что вы должны что-то сделатьдовольно хакерски, чтобы избежать переполнения стека.

Ваше описание не очень понятно (вы описываете как проблему, которую вы испытываете, так и нерабочие решения, которые вы пытаетесь одновременно,сбивает с толку), но звучит так, как будто вы пытаетесь сделать что-то вроде:

if (IsValid(value))
{
   _Property = value;
}
else
{
   _Property = GetValueFromDialog();
}

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

Ответ в этом случае заключается в использовании внедрения зависимостей.Создайте интерфейс с именем IDialogService:

interface IDialogService
{
   object GetValueFromDialog();
}

Теперь добавьте это свойство в модель представления:

public IDialogService DialogService { get; set; }

Код выше:

if (IsValid(value))
{
   _Property = value;
}
else
{
   _Property = DialogService.GetValueFromDialog();
}

Создатьдиалоговый сервис для использования в вашем приложении WPF, который фактически выдает диалог и получает результат.Когда вы создаете экземпляр модели представления в своем приложении, сделайте следующее:

MyViewModel vm = new MyViewModel { DialogService = new WpfDialogService(); }

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

Для своих юнит-тестов создайте фиктивный диалог, который выглядит следующим образом:

public class MockDialogService : IDialogService
{
   private object Result;

   public MockDialogService(object result)
   {
      Result = result;
   }

   public object GetValueFromDialog() { return Result; }
}

Затем вы можете написать тест, например:

MyViewModel vm = new MyViewModel { DialogService = MockDialogService(ExpectedResult) };
vm.Property = InvalidValue;
Assert.AreEqual(ExpectedResult, vm.Property);

Вышеприведенный пример - скорее эскизрешения, а не решения - в зависимости от того, как ваше приложение использует диалоги, вам может понадобиться гораздо больше функций, чем показано здесь.Если вы посмотрите на фреймворки MVVM, то обнаружите, что многие из них реализуют те или иные диалоговые сервисы.

0 голосов
/ 15 июля 2011

Вы можете использовать каркас, такой как MVVMLight или Prism, который позволяет вам передавать полезные нагрузки между различными объектами полностью отделенными способами.MVVMLight очень легкий по сравнению с Prism.У него есть концепция Messanger, которая действует как шина событий всей системы.Точно так же у вас есть EventAggregator в Prism.

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