В настоящее время я работаю с шаблоном Microsoft MVVM и считаю, что отсутствие подробных примеров меня разочаровывает. Включенный пример ContactBook показывает очень мало обработки команд, и единственный другой пример, который я нашел, взят из статьи MSDN Magazine, где концепции похожи, но использует немного другой подход и по-прежнему не имеет какой-либо сложности. Есть ли какие-нибудь достойные примеры MVVM, которые хотя бы показывают основные операции CRUD и переключение диалога / контента?
Все предложения были действительно полезны, и я начну составлять список хороших ресурсов.
Фреймворки / шаблоны
Полезные статьи
- Приложения WPF с шаблоном проектирования модель-представление-представление модели
- Проверка данных в .NET 3.5
- Использование ViewModel для предоставления значимых сообщений об ошибках проверки
- ViewModel и проверка модели на основе действий
- Диалоги
- Привязки команд в MVVM
- Больше, чем просто MVC для WPF
- Пример приложения MVVM + Mediator
Скринкасты
Дополнительные библиотеки
- Улучшенная реализация шаблона медиатора в WPF Disciples (я настоятельно рекомендую это для приложений с более сложной навигацией)
- Мессенджер MVVM Light Toolkit
Ответы:
К сожалению, нет ни одного отличного примера приложения MVVM, которое бы все делало, и есть много разных подходов к этому. Во-первых, вы можете ознакомиться с одной из существующих платформ приложений (Prism - достойный выбор), потому что они предоставляют вам удобные инструменты, такие как внедрение зависимостей, команды, агрегация событий и т. Д., Чтобы легко опробовать различные подходящие вам шаблоны. .
Релиз призмы:
http://www.codeplex.com/CompositeWPF
Он включает в себя довольно приличный пример приложения (биржевой трейдер) вместе с множеством небольших примеров и инструкций. По крайней мере, это хорошая демонстрация нескольких общих подшаблонов, которые люди используют, чтобы заставить MVVM действительно работать. Думаю, у них есть примеры как для CRUD, так и для диалогов.
Prism не обязательно подходит для каждого проекта, но с ней хорошо познакомиться.
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, который предоставляет команды для действий фиксации и отмены, событие, позволяющее представлению узнать, что диалоговое окно готово к закрытию, и все остальное, что вам понадобится во всех ваших диалогах.
Общее представление для вашего диалога - это может быть окно или настраиваемый элемент управления типа «модальное» наложение. По сути, это презентатор контента, в который мы выгружаем модель просмотра, и он обрабатывает проводку для закрытия окна - например, при изменении контекста данных вы можете проверить, унаследована ли новая модель просмотра от вашего базового класса, и если это так, подписаться на соответствующее событие закрытия (обработчик назначит результат диалога). Если вы предоставляете альтернативную универсальную функцию закрытия (например, кнопку X), вы также должны запустить соответствующую команду закрытия в ViewModel.
Где-то вам нужно предоставить шаблоны данных для ваших ViewModels, они могут быть очень простыми, особенно потому, что у вас, вероятно, есть представление для каждого диалогового окна, инкапсулированного в отдельный элемент управления. Тогда шаблон данных по умолчанию для ViewModel будет выглядеть примерно так:
<DataTemplate DataType="{x:Type vmodels:AddressEditViewModel}"> <views:AddressEditView DataContext="{Binding}" /> </DataTemplate>
Диалоговое представление должно иметь доступ к ним, потому что в противном случае оно не будет знать, как отображать ViewModel, за исключением пользовательского интерфейса общего диалогового окна, его содержимое в основном следующее:
<ContentControl Content="{Binding}" />
Шаблон неявных данных отобразит представление на модель, но кто его запускает?
Это не совсем mvvm часть. Один из способов сделать это - использовать глобальное событие. Я думаю, что лучше всего использовать настройку типа агрегатора событий, предоставляемую посредством внедрения зависимостей - таким образом, событие является глобальным для контейнера, а не для всего приложения. Prism использует фреймворк Unity для семантики контейнеров и внедрения зависимостей, и в целом мне очень нравится Unity.
Обычно для корневого окна имеет смысл подписаться на это событие - оно может открыть диалоговое окно и установить для него контекст данных ViewModel, который передается с поднятым событием.
Такая настройка позволяет ViewModels просить приложение открыть диалоговое окно и реагировать на действия пользователя в нем, ничего не зная о пользовательском интерфейсе, поэтому по большей части MVVM-ность остается полной.
Однако бывают случаи, когда пользовательский интерфейс должен поднимать диалоги, что может немного усложнить задачу. Рассмотрим, например, зависит ли положение диалогового окна от положения кнопки, которая его открывает. В этом случае вам нужно иметь некоторую информацию, специфичную для пользовательского интерфейса, когда вы запрашиваете открытие диалога. Обычно я создаю отдельный класс, который содержит ViewModel и некоторую соответствующую информацию пользовательского интерфейса. К сожалению, некоторая связь здесь кажется неизбежной.
Псевдокод обработчика кнопки, который вызывает диалог, требующий данных о положении элемента:
Диалоговое представление будет привязано к данным положения и передаст содержащуюся в нем ViewModel внутреннему
ContentControl
. Сама ViewModel по-прежнему ничего не знает о пользовательском интерфейсе.В общем, я не использую
DialogResult
свойство returnShowDialog()
метода и не ожидаю, что поток заблокируется, пока диалоговое окно не будет закрыто. Нестандартный модальный диалог не всегда работает подобным образом, а в составной среде вы часто не хотите, чтобы обработчик событий блокировал подобное. Я предпочитаю, чтобы ViewModel занимался этим - создатель ViewModel может подписываться на соответствующие события, устанавливать методы фиксации / отмены и т. Д., Поэтому нет необходимости полагаться на этот механизм пользовательского интерфейса.Итак, вместо этого потока:
Я использую:
Я предпочитаю этот способ, потому что большинство моих диалогов - это неблокирующие псевдомодальные элементы управления, и сделать это таким способом кажется более простым, чем обходиться без него. Также легко провести модульное тестирование.
источник
Джейсон Долинджер сделал хороший скринкаст MVVM. Как сказал Егор, нет ни одного хорошего примера. Они все кончены. Большинство из них являются хорошими примерами MVVM, но не тогда, когда вы сталкиваетесь со сложными проблемами. У каждого свой путь. У Лорана Бюньона также есть хороший способ общения между моделями просмотра. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch также является хорошим примером. У Пола Стовела есть хороший пост, который тоже многое объясняет с его фреймворком Magellan.
источник
Вы смотрели на Калибурна ? В образце ContactManager много хороших вещей. Общие образцы WPF также предоставляют хороший обзор команд. Документация довольно хорошая, форумы активны. Рекомендуемые!
источник
Нашел это полезным. Также есть код.
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
источник
Здесь я добавляю ссылку на приложение WPF (Inventory Management App), использующее архитектуру MVVM, разработанную мной.
Его интерфейс потрясающий. https://github.com/shivam01990/InventoryManagement
источник
В примере проекта в среде Cinch показаны основные инструменты CRUD и навигации. Это довольно хороший пример использования MVVM и включает в себя статью, состоящую из нескольких частей, объясняющую его использование и мотивацию.
источник
Я также разделял ваше разочарование. Я пишу заявку, и у меня были следующие 3 требования:
Все, что я нашел, были кусочками и кусочками, поэтому я просто начал писать это как мог. После того, как я немного погрузился в это, я понял, что могут быть другие люди (такие как вы), которые могут использовать эталонное приложение, поэтому я реорганизовал общий материал в структуру приложения WPF / MVVM и выпустил его под LGPL. Я назвал его SoapBox Core . Если вы перейдете на страницу загрузок, вы увидите, что оно поставляется с небольшим демонстрационным приложением, и исходный код этого демонстрационного приложения также доступен для загрузки. Надеюсь, вы найдете это полезным. Кроме того, напишите мне на scott {at} soapboxautomation.com, если вам нужна дополнительная информация.
РЕДАКТИРОВАТЬ : Также опубликована статья CodeProject, объясняющая, как это работает.
источник
Я написал простой пример MVVM с нуля в проекте кода, вот ссылка MVVM WPF шаг за шагом . Он начинается с простой трехуровневой архитектуры и дает вам возможность использовать некую структуру, такую как PRISM.
источник
Даже я разделял разочарование, пока не взял дело в свои руки. Я запустил IncEditor.
IncEditor ( http://inceditor.codeplex.com ) - редактор, который пытается познакомить разработчиков с WPF, MVVM и MEF. Я запустил его, и мне удалось получить некоторые функции, такие как поддержка «темы». Я не разбираюсь в WPF, MVVM или MEF, поэтому не могу добавить в него много функций. Я искренне прошу вас, ребята, сделать его лучше, чтобы психи вроде меня могли лучше понять это.
источник