Подтвердить что ты не робот

Как WPF-преобразователи могут использоваться в шаблоне MVVM?

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

ViewModel - это в основном конвертер значений на стероидах. Требуется "сырые" данные и преобразует его во что-то приятное для восприятия, и наоборот. Если вы когда-либо обнаруживаете, что привязываете свойство element к ViewModel свойство, и вы используете конвертер значений, остановитесь! Почему бы просто не создать свойство в ViewModel, которое предоставляет "отформатированные" данные, а затем отбрасывает конвертер значений вообще?

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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

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

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

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

Ответ 5

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

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

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

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

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

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