Конкретные примеры совместного использования состояния между несколькими моделями представления (WPF MVVM) - PullRequest
31 голосов
/ 05 января 2011

У меня есть проект WPF / Entity Framework (4.0) со многими объектами.Я хотел бы построить приложение так, чтобы у меня была возможность выбора состояния объекта для всех моделей представления.

Например: у нас есть классы автомобилей, водителей, пассажиров и грузов.У нас также есть UserControls для CarList, DriverList и т. Д. И окна редактора для CarEditor, DriverEditor и т. Д. Кроме того, у нас есть viewmodels для всех этих (CarListViewModel, DriverListViewModel, CargoEditorViewModel и т. Д.).Все это составляет стыкуемый интерфейс, в котором у пользователя может быть открыто несколько списков объектов, редакторов и средств просмотра.

Мне нужен конкретный пример кода, как подключить несколько моделей представления так, чтобы при выборе автомобиля в CarListзаставить этот автомобиль работать в CarEditorView, но также быть выбранным в любом другом представлении, для которого действителен контекст (например, DriverByCarView- или просто DriverList, если есть предикат фильтра).

Естьколичество предложений и обсуждений на основе этого вопроса.Два метода, которые, по-видимому, доминируют:

  • 3018307 : обсуждение общего состояния путем упоминания подсистемы обмена сообщениями
  • 1159035 : обсуждение состояниясовместное использование с помощью включающей модели представления

Один из этих подходов лучше другого?

У кого-нибудь есть конкретный пример того или другогоиз этих методов в форме проекта написания или небольшого кода?

Я все еще изучаю WPF, так что ссылки на точки входа для чтения основ API приветствуются, но рассмотрение примеров кодакуда я обычно хожу.

Спасибо


На случай, если кому-то интересно, вот еще несколько подобных обсуждений:

  • 3816961 : Обсуждается возвращение нескольких моделей представления в зависимости от типа объекта (т. Е. Набор произвольных типов, привязанных к конкретному интерфейсу)
  • 1928130 : обсуждается, является ли хорошей идеей объединять модели представления как профессиональныехарактеристики других моделей представления (например, модель представления MainWindow, состоящая из панельных моделей представления)
  • 1120061 : по существу обсуждается, использовать ли стратегию модели представления для модели или элемент представления модели для представлениястратегия.
  • 4244222 : обсуждает, следует ли вкладывать модели представления при использовании иерархии вложенных объектов.
  • 4429708 : обсуждается совместное использование коллекций между моделями представлениянапрямую, но не вдаваться в подробности.
  • Элемент списка : обсуждается управление несколькими выборами в рамках одной модели представления.

1 Ответ

12 голосов
/ 05 января 2011

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

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

В Prism мессенджер является EventAggregator и используется для публикации и подписки на сообщения.

Обновление

Помимо архитектурных преимуществ, которые дает EventAggregator, он также реализует слабые события, чтобы предотвратить проблемы утечки памяти с подписчиками, которые явно не отписываются.

Пожалуйста, смотрите следующую документацию по EventAggregator:

http://msdn.microsoft.com/en-us/library/ff649187.aspx

Призма:

http://compositewpf.codeplex.com/

Пример призмы

public class ViewModel1
{
    private readonly IEventAggregator _eventService;
    private Car _selectedCar;

    public ViewModel1(IEventAggregator eventService)
    {
        _eventService = eventService;
    }

    //Databound property...
    public Car SelectedCar
    {
        set
        {
            _selectedCar = value;

            var msg = new CarSelectedMessage { Car = _selectedCar };

            _eventService.GetEvent<CarSelectedEvent>().Publish(msg);
        }
    }
}

public class ViewModel2
{
    public ViewModel2(IEventAggregator eventService)
    {
        eventService.GetEvent<CarSelectedEvent>().Subscribe(msg =>
        {
            //DoStuff with msg...
        });
    }
}

public class Car {}

public class CarMessage
{
    public Car Car { get; set; }
}

public class CarSelectedEvent : CompositePresentationEvent<CarMessage> {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...