MVVM – WPF 数据绑定


在本章中,我们将学习数据绑定如何支持 MVVM 模式。数据绑定是 MVVM 区别于其他 UI 分离模式(如 MVC 和 MVP)的关键功能。

  • 对于数据绑定,您需要构造一个视图或一组 UI 元素,然后需要绑定将指向的其他对象。

  • 视图中的 UI 元素绑定到 ViewModel 公开的属性。

  • View 和 ViewModel 的构建顺序取决于具体情况,因为我们首先介绍了 View。

  • 构造 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 公开的 Students 集合。

  • 您还可以看到 Student 模型的属性也有自己单独的绑定,并且这些绑定到 Textboxes 和 TextBlock。

  • ItemsControl 的 ItemSource 能够绑定到 Students 属性,因为视图的整体 DataContext 设置为 ViewModel。

  • 这里属性的单独绑定也是 DataContext 绑定,但由于 ItemSource 的工作方式,它们并不针对 ViewModel 本身进行绑定。

  • 当项目源绑定到其集合时,它会在呈现时为每个项目呈现一个容器,并将该容器的 DataContext 设置为该项目。因此,行中每个文本框和文本块的整体 DataContext 将是集合中的单个 Student。您还可以看到,TextBox 的这些绑定是 TwoWay 数据绑定,而 TextBlock 的这些绑定是 OneWay 数据绑定,因为您无法编辑 TextBlock。

当您再次运行该应用程序时,您将看到以下输出。

WPF 数据绑定主窗口

现在让我们将第一行第二个文本框中的文本从 Allin 更改为 Upston,然后按 Tab 键失去焦点。您将看到 TextBlock 文本也已更新。

更新的文本块

这是因为 TextBox 的绑定设置为 TwoWay 并且它也会更新模型,并且再次从模型更新 TextBlock。