Теперь, когда свойство DataContext
для Window
установлено в модель представления, потребуется обновить привязки элементов управления в разметке XAML. Начиная с поля со списком, модифицируйте разметку за счет добавления свойства ItemsSource
:
ItemsSource="{Binding Cars}" />
Прием работает, т.к. контекстом данных для Window
является MainWindowViewModel
, a Cars
— открытое свойство модели представления. Вспомните, что конструкции привязки обходят дерево элементов до тех пор, пока не найдут контекст данных. Далее понадобится обновить привязки для элементов управления Button
. Задача проста; поскольку привязки уже установлены на уровне окна, нужно лишь модифицировать конструкции привязки, чтобы они начинались со свойства DataContext
:
Margin="5,0,5,0" Padding="4, 2"
Command="{Binding Path=DataContext.AddCarCmd,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}"
CommandParameter="{Binding ElementName=cboCars, Path=ItemsSource}"/>
Margin="5,0,5,0" Padding="4, 2"
Command="{Binding Path=DataContext.DeleteCarCmd,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}"
CommandParameter="{Binding ElementName=cboCars, Path=SelectedItem}" />
Margin="5,0,5,0" Padding="4, 2"
Command="{Binding Path=DataContext.ChangeColorCmd,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}"
CommandParameter="{Binding ElementName=cboCars, Path=SelectedItem}"/>
Итоговые сведения о моделях представлений
Верите или нет, но вы только что закончили построение первого WPF-приложения MWM. Вы можете подумать: "Это не реалистичное приложение. Как насчет данных? Данные в примере жестко закодированы". И вы будете совершенно правы. Это не реальное приложение, а лишь демонстрация. Однако в ней легко оценить всю прелесть паттерна MWM. Представлению ничего не известно о том, откуда поступают данные; оно просто привязывается к свойству модели представления. Реализации модели представления можно менять, скажем, использовать версию с жестко закодированными данными во время тестирования и версию, обращающуюся к базе данных, в производственной среде.
Можно было бы обсудить еще немало вопросов, в том числе разнообразные инфраструктуры с открытым кодом, паттерн "Локатор модели представления" (View Model Locator) и множество разных мнений на предмет того, как лучше реализовывать паттерн MWM. В том и заключается достоинство паттернов проектирования программного обеспечения — обычно существует много правильных способов их реализации, и вам необходимо лишь отыскать стиль, который наилучшим образом подходит к имеющимся требованиям.
Обновление проекта AutoLot.Dal для MWM
Если вы хотите обновить проект AutoLot.Dal
для MWM, то должны применить изменения, которые вносились в Car
, ко всем сущностям в проекте AutoLot.Dal.Models
, включая BaseEntity
.
Резюме
В главе рассматривались аспекты WPF, относящиеся к поддержке паттерна MWM. Сначала было показано, каким образом связывать классы моделей и коллекции с помощью системы уведомлений в диспетчере привязки. Демонстрировалась реализация интерфейса INotifyPropertyChanged
и применение классов наблюдаемых коллекций для обеспечения синхронизации пользовательского интерфейса и связанных с ним данных.
Вы научились добавлять код проверки достоверности к модели с применением интерфейсов IDataErrorInfo
и INotifyDataErrorInfо
, а также проверять наличие ошибок, основанных на аннотациях данных. Было показано, как отображать обнаруженные ошибки проверки достоверности в пользовательском интерфейсе, чтобы пользователь знал о проблеме и мог ее устранить. Вдобавок был создан стиль и специальный шаблон элементов управления для визуализации ошибок более эффективным способом.
В заключение вы узнали, каким образом собирать все компоненты вместе за счет добавления модели представления, а также приводить в порядок разметку и отделенный код пользовательского интерфейса, чтобы усилить разделение обязанностей.
Часть IX
ASP.NET Core
Глава 29
Введение в ASP.NET Core