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

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


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

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

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

видеоролики

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

9 ответов


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

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

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

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

CRUD: Эта часть довольно проста, WPF двухсторонние привязки позволяют очень легко редактировать большинство данных. Реальный трюк-предоставить модель,которая упрощает настройку пользовательского интерфейса. По крайней мере, вы хотите убедиться, что ваш ViewModel (или бизнес-объект) реализует INotifyPropertyChanged для поддержки привязки, и вы можете привязать свойства прямо к элементам управления UI, но вы также можете реализовать 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, который держит его и команды для сохранения / удаления - и вы готовы связать UI прямо с свойства модели.

вид будет выглядеть примерно так (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 от вашего базового класса, и если да, подписаться на соответствующее событие закрытия (обработчик назначит результат диалога). Если вы предоставляете альтернативную универсальную функцию закрытия (например, кнопку 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 и некоторую соответствующую информацию UI. К сожалению, некоторые связи там неизбежны.

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

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, но не тогда, когда вы попадаете в сложные проблемы. У каждого свой путь. У Laurent Bugnion есть хороший способ общения между viewmodels. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch также является хорошим примером. Paul Stovel имеет хороший в должности это многое объясняет с его рамках Магеллан.


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


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

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


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


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

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

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

редактировать: также выложили статья 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