Как можно использовать конвертеры WPF в шаблоне MVVM? - PullRequest
17 голосов
/ 17 июня 2009

Допустим, у меня есть представление, привязанное к ViewModel A , которое имеет наблюдаемую коллекцию Клиенты .

Преимущество этого шаблона MVVM состоит в том, что я также могу привязать View к ViewModel B , которая заполняет его различными данными.

Но что, если в моих Просмотр конвертеров конвертер для отображения моих клиентов, например, У меня есть «ContractToCustomerConverter», который принимает контракт и возвращает соответствующего клиента для отображения.

Проблема в том, что конвертер существует вне шаблона MVVM и поэтому не знает, что у моей ViewModel есть другой источник для клиентов.

  • есть ли способ для View передать ViewModel в конвертер , чтобы он участвовал в развязке, которую обеспечивает шаблон MVVM?
  • есть ли способ как-то включить конвертер в мою ViewModel , чтобы конвертер использовал текущие зависимости, которые есть у ViewModel?
  • или являются конвертерами прославленного кода позади и поэтому не используются в шаблоне MVVM, поэтому, если вы используете MVVM, вы просто создаете свои собственные "конвертеры" (методы в своем классе ViewModel), которые возвращают такие вещи, как объекты изображений, объекты видимости, FlowDocuments и т. д., которые будут использоваться в представлении вместо того, чтобы вообще использовать конвертеры?

(Я столкнулся с этими вопросами после того, как увидел использование конвертеров в демонстрационном приложении WPF, которое поставляется вместе с MVVM Template Toolkit , см. «Образец Messenger» после его распаковки.)

Ответы [ 5 ]

12 голосов
/ 17 июня 2009

Я обычно вообще не использую конвертеры в MVVM, за исключением чисто пользовательских задач (например, BooleanToVisibilityConverter). ИМХО, вам лучше объявить свойство Customer типа CustomerViewModel в ContractViewModel, а не использовать ContractToCustomerConverter

11 голосов
/ 17 июня 2009

В этом разговоре есть комментарий, который согласуется с позицией Кента, вообще не использовать конвертеры, интересно:

ViewModel - это, в основном, конвертер значений для стероидов. Требуются «сырые» данные и превращает его в нечто удобное для презентации, и наоборот. Если Вы когда-либо связываете свойство элемента с ViewModel свойство, и вы используете конвертер значений, остановитесь! Почему бы просто не создать свойство ViewModel, которое предоставляет «отформатированные» данные, а затем отбрасывает конвертер значений в целом?

А в этот разговор :

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

8 голосов
/ 17 июня 2009

Преобразователи редко должны использоваться с MVVM. На самом деле, я стараюсь не использовать их вообще. ВМ должна делать все, что нужно представлению, чтобы выполнить свою работу. Если представлению требуется Customer на основе Contract, на ВМ должно быть свойство Customer, которое обновляется логикой ВМ при каждом изменении Contract.

Преимущество этого шаблона MVVM состоит в том, что я также могу связать View с ViewModel B, которая заполняет его различными данными.

Я оспариваю это утверждение. По моему опыту, представления не разделяются между различными типами виртуальных машин, и при этом это не цель MVVM.

5 голосов
/ 18 июня 2009

Для тех, кто фактически говорит "нетривиальные преобразователи" в представлении, как вы справляетесь со следующим?

Допустим, у меня есть модель климатических датчиков, которая представляет временные ряды показаний различных приборов (барометр, гигрометр, термометр и т. Д.) В данном месте.

Допустим, моя модель представления предоставляет видимую коллекцию датчиков из моей модели.

У меня есть представление, содержащее инструментарий WPF DataGrid, которое привязывается к модели представления со свойством ItemsSource, установленным для наблюдаемой коллекции датчиков. Как мне представить вид каждого инструмента для данного датчика? При отображении небольшого графика (вспомните Edward Tufte sparkline здесь), который генерируется путем преобразования временного ряда в источник изображения с использованием преобразователя (TimeSeriesToSparklineConverter)

Вот как я думаю о MVVM: Модель предоставляет данные для просмотра моделей. Модель представления предоставляет поведение, данные модели и состояние для просмотра. Представления выполняют визуальное представление данных модели и предоставляют интерфейс для поведения, согласующегося с состоянием модели представления.

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

Поэтому, если я хочу представить поведение, данные модели и заданное состояние для определенной модели представления в интерфейсе командной строки вместо графического интерфейса WPF, я не хочу, чтобы ни моя модель, ни моя модель представления содержали изображения. Это неправильно? Должны ли мы иметь SensorCollectionGUIViewModel и SensorCollectionCommandLineViewModel? Мне это кажется неправильным: я считаю модель представления абстрактным представлением представления, а не конкретным и привязанным к конкретной технологии, как предполагают эти имена.

Вот где я нахожусь в моем постоянно развивающемся понимании MVVM. Так что для тех, кто говорит не использовать конвертеры, что вы здесь делаете?

0 голосов
/ 06 мая 2011

Я добавлю свои 2 цента к этой дискуссии.

Я использую конвертеры, где это имеет смысл.

Пояснение: Есть случаи, когда вам нужно представить 1 значение в модели несколькими способами в пользовательском интерфейсе. Я выставляю это значение через 1 тип. Другой тип обрабатывается через конвертер. Если бы вы выставили 1 значение через 2 свойства в ВМ, вам бы пришлось вручную обрабатывать уведомления об обновлениях.

Например, у меня есть модель с 2-мя отверстиями: TotalCount, DoneCount. Теперь я хочу, чтобы оба этих значения отображались в TextBlocks, и, кроме того, я хочу, чтобы отображался процент выполнения.

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

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

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