在本章中,我们将学习数据绑定如何支持MVVM模式.数据绑定是将MVVM与其他UI分离模式(如MVC和MVP)区分开来的关键特性.
对于数据绑定,您需要要构建一个视图或一组UI元素,然后你需要一些绑定指向的其他对象.
一个UI元素视图绑定到ViewModel公开的属性.
构建View和ViewModel的顺序取决于具体情况,正如我们已经介绍的那样视图优先.
构建View和ViewModel,并将View的DataContext设置为ViewModel.
绑定可以是OneWay或TwoWay数据绑定,以在View和ViewModel之间来回传输数据.
<让我们看一下同一个例子中的数据绑定.下面是StudentView的XAML代码.
<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.
ItemsControl的ItemSource能够绑定到Students属性,因为View的整个DataContext设置为ViewModel.
此处属性的单独绑定也是DataContext绑定,但由于ItemSource的工作方式,它们不会绑定ViewModel本身.
当项目源绑定到其集合时,它会在呈现时为每个项目呈现一个容器,并将该容器的DataContext设置为该项目.因此,行中每个文本框和文本块的整体DataContext将成为集合中的单个学生.你还可以看到TextBoxes的这些绑定是TwoWay数据绑定,而对于TextBlock,它是OneWay数据绑定,因为你无法编辑TextBlock.
再次运行此应用程序时,您将看到以下输出.
现在让我们将第一行第二个文本框中的文本从Allain更改为Upston,然后按Tab键失去焦点.您将看到TextBlock文本也已更新.
这是因为TextBoxes的绑定设置为TwoWay并且它也更新了Model,并且再次从模型中更新了TextBlock.