MVVM - привязки данных WPF
В этой главе мы узнаем, как привязка данных поддерживает шаблон MVVM. Привязка данных - это ключевая функция, которая отличает MVVM от других шаблонов разделения пользовательского интерфейса, таких как MVC и MVP.
Для привязки данных вам необходимо создать представление или набор элементов пользовательского интерфейса, а затем вам понадобится какой-то другой объект, на который будут указывать привязки.
Элементы пользовательского интерфейса в представлении привязаны к свойствам, которые предоставляет ViewModel.
Порядок построения View и ViewModel зависит от ситуации, так как мы сначала рассмотрели View.
Создается представление и ViewModel, и DataContext представления устанавливается в ViewModel.
Привязки могут быть привязками данных OneWay или TwoWay для обмена данными между View и ViewModel.
Давайте посмотрим на привязки данных в том же примере. Ниже представлен код XAML для StudentView.
<UserControl x:Class = "MVVMDemo.Views.StudentView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local = "clr-namespace:MVVMDemo.Views"
xmlns:viewModel = "clr-namespace:MVVMDemo.ViewModel"
xmlns:vml = "clr-namespace:MVVMDemo.VML"
vml:ViewModelLocator.AutoHookedUpViewModel = "True"
mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300">
<!--<UserControl.DataContext>
<viewModel:StudentViewModel/>
</UserControl.DataContext>-->
<Grid>
<StackPanel HorizontalAlignment = "Left">
<ItemsControl ItemsSource = "{Binding Path = Students}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}"
Width = "100" Margin = "3 5 3 5"/>
<TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"
Width = "100" Margin = "0 5 3 5"/>
<TextBlock Text = "{Binding Path = FullName, Mode = OneWay}"
Margin = "0 5 3 5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
Если вы посмотрите на приведенный выше код XAML, вы увидите, что ItemsControl привязан к коллекции студентов, предоставляемой ViewModel.
Вы также можете видеть, что свойство модели Student также имеет свои собственные индивидуальные привязки, и они привязаны к Textboxes и TextBlock.
ItemSource элемента ItemsControl может быть привязан к свойству Student, поскольку для общего контекста данных для представления установлено значение ViewModel.
Отдельные привязки свойств здесь также являются привязками DataContext, но они не привязаны к самой ViewModel из-за того, как работает ItemSource.
Когда источник элемента связывается со своей коллекцией, он визуализирует контейнер для каждого элемента при визуализации и устанавливает DataContext этого контейнера для элемента. Таким образом, общий DataContext для каждого текстового поля и текстового блока в строке будет отдельным Student в коллекции. И вы также можете видеть, что эти привязки для TextBoxes являются привязкой данных TwoWay, а для TextBlock - привязкой данных OneWay, поскольку вы не можете редактировать TextBlock.
Когда вы снова запустите это приложение, вы увидите следующий результат.
Давайте теперь изменим текст во втором текстовом поле первой строки с Allain на Upston и нажмем вкладку, чтобы потерять фокус. Вы увидите, что текст TextBlock также обновлен.
Это связано с тем, что привязки TextBoxes установлены на TwoWay, и он также обновляет модель, а из модели снова обновляется TextBlock.