Хорошие примеры шаблона MVVM



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





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



Рамки/Шаблоны




полезное Статьи




видеоролики




Дополнительные Библиотеки



1353   9  

9 ответов:

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

выпуск призмы:
http://www.codeplex.com/CompositeWPF

он включает в себя довольно приличный пример приложения (биржевой трейдер) наряду с большим количеством небольших примеров и как С. По крайней мере, это хорошая демонстрация нескольких общих подшаблонов люди используют, чтобы сделать MVVM на самом деле работать. У них есть примеры как для CRUD, так и для диалогов, я считаю.

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

CRUD: Эта часть довольно проста, WPF двухсторонние привязки позволяют очень легко редактировать большинство данных. Настоящая хитрость заключается в том, чтобы предоставить модель, которая упрощает настройку пользовательского интерфейса. По крайней мере, вы хотите убедиться, что ваш ViewModel (или бизнес-объект) реализует INotifyPropertyChanged для поддержки привязки, и вы можете привязать свойства прямо к элементам управления пользовательского интерфейса, но вы также можете реализовать IDataErrorInfo для проверки. Как правило, если вы используете какую-то настройку решения ORM Круд-это несложно.

эта статья демонстрирует простые операции crud: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx

он построен на LinqToSql, но это не имеет отношения к примеру - все, что важно, это то, что ваши бизнес-объекты реализуют INotifyPropertyChanged (какие классы генерируются LinqToSql). MVVM не является точкой этого примера, но я не думаю, что это имеет значение в данном случае.

в этой статье показано, проверка данных
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx

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

большую часть времени вы можете взять объект (модель), созданный некоторым ORM, и обернуть его в ViewModel, который содержит его и команды для сохранения / удаления - и вы готовы привязать пользовательский интерфейс прямо к свойства модели.

вид будет выглядеть примерно так (ViewModel имеет свойство Item который содержит модель, как класс, созданный в ORM):

<StackPanel>
   <StackPanel DataContext=Item>
      <TextBox Text="{Binding FirstName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
      <TextBox Text="{Binding LastName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
   </StackPanel>
   <Button Command="{Binding SaveCommand}" />
   <Button Command="{Binding CancelCommand}" />
</StackPanel>

окна: Диалоги и MVVM немного сложнее. Я предпочитаю использовать аромат медиаторного подхода с диалогами, вы можете прочитать немного больше об этом в этом вопросе StackOverflow:
пример диалога WPF MVVM

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

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

общий вид для вашего диалогового окна-это может быть окно или пользовательский элемент управления "модальным" типом наложения. По своей сути это презентер контента, в который мы сбрасываем viewmodel, и он обрабатывает проводка для закрытия окна - например, при изменении контекста данных вы можете проверить, наследуется ли новый ViewModel от вашего базового класса, и если это так, подпишитесь на соответствующее событие close (обработчик назначит результат диалога). Если вы предоставляете альтернативную универсальную функцию закрытия (например, кнопку X), вы также должны выполнить соответствующую команду закрытия на ViewModel.

где-то вам нужно предоставить шаблоны данных для ваших ViewModels, они могут будьте очень просты, тем более, что у вас, вероятно, есть представление для каждого диалога, инкапсулированного в отдельный элемент управления. Шаблон данных по умолчанию для ViewModel будет выглядеть примерно так:

<DataTemplate DataType="{x:Type vmodels:AddressEditViewModel}>
   <views:AddressEditView DataContext={Binding} />
</DataTemplate>

диалоговое окно должно иметь доступ к ним, потому что в противном случае он не будет знать, как показать ViewModel, помимо общего диалогового интерфейса его содержимое в основном таково:

<ContentControl Content={Binding} />

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

это не так-mvvm часть. Один из способов сделать это-использовать глобальное событие. Я думаю, что лучше всего использовать настройку типа агрегатора событий, предоставляемую посредством инъекции зависимостей-таким образом, событие является глобальным для контейнера, а не для всего приложения. Prism использует Unity framework для семантики контейнеров и инъекции зависимостей, и в целом мне нравится Unity совсем немного.

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

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

однако бывают случаи, когда пользовательский интерфейс должен вызывать диалоги, что может сделать вещи немного сложнее. Рассмотрим, например, если позиция диалога зависит о расположении кнопки, которая ее открывает. В этом случае вам нужно иметь некоторую информацию о пользовательском интерфейсе, когда вы запрашиваете открытие диалогового окна. Я обычно создаю отдельный класс, который содержит ViewModel и некоторую соответствующую информацию пользовательского интерфейса. К сожалению, некоторые сцепления там кажутся неизбежными.

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

ButtonClickHandler(sender, args){
    var vm = DataContext as ISomeDialogProvider; // check for null
    var ui_vm = new ViewModelContainer();
    // assign margin, width, or anything else that your custom dialog might require
    ...
    ui_vm.ViewModel = vm.SomeDialogViewModel; // or .GetSomeDialogViewModel()
    // raise the dialog show event
}

диалоговое окно будет привязываться к данным позиции и передавать содержащуюся ViewModel во внутренний ContentControl. Сама ViewModel по-прежнему ничего не знает о пользовательском интерфейсе.

вообще я не использую DialogResult возврат имущества ShowDialog() метод или ожидать, что поток будет блокировать, пока диалоговое окно не будет закрыто. Нестандартное модальное диалоговое окно не всегда работает так, и в составной среде вы часто не хотите, чтобы обработчик событий блокировал это так или иначе. Я предпочитаю, чтобы ViewModels занимались этим - создатель ViewModel может подписаться на его соответствующие события, установить методы фиксации / отмены и т. д., Поэтому нет необходимости полагаться на этот механизм пользовательского интерфейса.

так вместо этого потока:

// in code behind
var result = somedialog.ShowDialog();
if (result == ...

я использую:

// in view model
var vm = new SomeDialogViewModel(); // child view model
vm.CommitAction = delegate { this.DoSomething(vm); } // what happens on commit 
vm.CancelAction = delegate { this.DoNothing(vm); } // what happens on cancel/close (optional)
// raise dialog request event on the container

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

Джейсон Dolinger сделан хороший видеоуроки из MVVM. Как сказал Егор, нет ни одного хорошего примера. Они все кончились. Большинство из них являются хорошими примерами MVVM, но не тогда, когда вы попадаете в сложные проблемы. У каждого свой путь. Лоран Bugnion имеет хороший способ общения между viewmodels, а также. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch также является хорошим примером. Пол Стовел имеет хороший post это тоже многое объясняет с его магеллановой структурой.

вы смотрели Калибурн? В образце ContactManager есть много хороших вещей. Общие примеры WPF также предоставляют хороший обзор команд. Документация довольно хорошая, и форумы активны. Рекомендуется!

нашел это полезным. Есть код тоже.

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

пример проекта в Cinch framework показывает основные инструменты CRUD и навигации. Это довольно хороший пример использования MVVM, и включает в себя мульти-часть статьи объясняя его использование и мотивации.

Я также разделил ваше разочарование. Я пишу заявление, и у меня были эти 3 требования:

  • расширяемый
  • WPF с MVVM
  • GPL совместимые примеры

все, что я нашел, были кусочки и куски, поэтому я просто начал писать его как можно лучше. После того, как я немного вошел в него, я понял, что могут быть другие люди (например, вы), которые могут использовать эталонное приложение, поэтому я переформулировал общий материал в WPF/MVVM рамки приложения и выпустили его под LGPL. Я назвал его SoapBox Core. Если вы перейдете на страницу загрузки, вы увидите, что она поставляется с небольшим демонстрационным приложением, и исходный код для этого демонстрационного приложения также доступен для загрузки. Надеюсь, вы найдете это полезным. Кроме того, напишите Мне по адресу scott {at} soapboxautomation.com если вы хотите больше информации.

EDIT: также опубликовано a статья CodeProject объясняя, как это работает.

даже я разделял разочарование, пока не взял дело в свои руки. Я начал Инцедтор.

IncEditor (http://inceditor.codeplex.com) - это редактор, который пытается познакомить разработчиков с WPF, MVVM & MEF. Я начал его и сумел получить некоторые функции, такие как поддержка "темы". Я не эксперт в WPF или MVVM или MEF, поэтому я не могу поместить в него много функциональности. Я искренне прошу вас, ребята, сделать это лучше, чтобы такие психи, как я, могли это понять лучше.

здесь я добавляю ссылку WPF (приложение для управления запасами) приложение который с помощью архитектура MVVM разработаны мной .

его интерфейс является удивительным. https://github.com/shivam01990/InventoryManagement

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

enter image description here

Comments

    Ничего не найдено.