MVVM - powiązania danych WPF
W tym rozdziale dowiemy się, jak powiązanie danych obsługuje wzorzec MVVM. Powiązanie danych jest kluczową funkcją, która odróżnia MVVM od innych wzorców separacji interfejsu użytkownika, takich jak MVC i MVP.
W przypadku powiązania danych musisz mieć skonstruowany widok lub zestaw elementów interfejsu użytkownika, a następnie potrzebujesz innego obiektu, na który będą wskazywać powiązania.
Elementy interfejsu użytkownika w widoku są powiązane z właściwościami, które są uwidaczniane przez ViewModel.
Kolejność, w jakiej są konstruowane View i ViewModel, zależy od sytuacji, ponieważ najpierw omówiliśmy widok.
View i ViewModel są konstruowane, a DataContext of the View jest ustawiana na ViewModel.
Powiązania mogą być powiązaniami danych OneWay lub TwoWay do przesyłania danych między View i ViewModel.
Przyjrzyjmy się powiązaniom danych w tym samym przykładzie. Poniżej znajduje się kod 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>
Jeśli spojrzysz na powyższy kod XAML, zobaczysz, że ItemsControl jest powiązany z kolekcją Students uwidocznioną przez ViewModel.
Możesz również zobaczyć, że właściwość modelu ucznia ma również swoje własne indywidualne powiązania, które są powiązane z Textboxami i TextBlock.
ItemSource of ItemsControl można powiązać z właściwością Students, ponieważ ogólny DataContext dla widoku jest ustawiony na ViewModel.
Poszczególne powiązania właściwości w tym miejscu są również powiązaniami DataContext, ale nie są one powiązane z samym ViewModel ze względu na sposób działania elementu ItemSource.
Gdy źródło elementu wiąże się ze swoją kolekcją, renderuje kontener dla każdego elementu podczas renderowania i ustawia DataContext tego kontenera na element. Zatem ogólny DataContext dla każdego pola tekstowego i bloku tekstowego w wierszu będzie stanowić indywidualnego Studenta w kolekcji. Możesz również zobaczyć, że te powiązania dla TextBox to powiązania danych TwoWay, a dla TextBlock jest to powiązanie danych OneWay, ponieważ nie możesz edytować TextBlock.
Po ponownym uruchomieniu tej aplikacji zobaczysz następujące dane wyjściowe.
Zmieńmy teraz tekst w drugim polu tekstowym pierwszego wiersza z Allain na Upston i naciśnij klawisz Tab, aby stracić fokus. Zobaczysz, że tekst TextBlock jest również aktualizowany.
Dzieje się tak, ponieważ powiązania TextBox są ustawione na TwoWay i aktualizuje również Model, a następnie z modelu ponownie aktualizowany jest TextBlock.