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 模型的属性也有自己的单独绑定,这些绑定已绑定到文本框和文本块。

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

  • 此处属性的单独绑定也是 DataContext 绑定,但由于 ItemSource 的工作方式,它们不会绑定到 ViewModel 本身。

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

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

WPF Data Bindings Main Window

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

Updated Text Block

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