MVVM模式在WPF中的应用

MVVM(Model-View-ViewModel)模式是一种设计模式,用于简化用户界面的开发。它将应用程序的UI(视图)与业务逻辑(模型)分离,通过ViewModel层来实现数据的双向绑定。本文将通过一个简单的例子,介绍如何在WPF应用程序中实现MVVM模式。

DataContext和数据绑定

MVVM模式中,DataContext是绑定数据的源,它定义了绑定操作的基础元素。数据绑定则是连接特定属性值和视觉控件的桥梁。例如,有一个WPF窗口,其中包含一个TextBox,希望在TextBox中显示窗口的标题,并能够通过修改TextBox的内容来修改窗口的标题。这就需要将TextBox的DataContext设置为窗口,并将Text属性绑定到窗口的Title属性上。以下是实现这一功能的XAML代码:

<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Name="MainWindow" Title="MainWindow" Height="111.194" Width="295.149"> <TextBox Name="TB1" Text="{Binding Title, ElementName=MainWindow, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Height="22" VerticalAlignment="Top" Width="248" /> </Window>

在这个例子中,为窗口指定了一个名称(MainWindow)。然后,将TextBox的Text属性绑定到MainWindow的Title属性上,以双向模式(TwoWay)进行绑定,并指定属性修改事件(PropertyChanged)作为触发更新操作的事件。运行这个示例,会发现窗口的标题会根据TextBox中输入的内容而改变。同样,如果修改代码来干预窗口的标题,也会看到TextBox内容的更新。

绑定数据模型

假设需要管理一个与外部类相关的绑定,这个类用于展示产品信息,包括产品代码和描述。以下是一个示例类,用于表示产品信息:

Public Class ItemData Public _code As String Public _des As String Public Property Code As String Get Return _code End Get Set(value As String) _code = value End Set End Property Public Property Description As String Get Return _des End Get Set(value As String) _des = value End Set End Property Public Sub New(ByVal code As String, ByVal des As String) _code = code _des = des End Sub End Class

这个类可以定义新的产品和实体,并初始化其基本属性。但是,这个类不能直接用作DataContext,除非它在变量中被引用。这意味着,如果希望执行绑定操作,需要在代码后台进行操作,例如,可以在窗口的Loaded事件中进行操作:

Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Dim item As New ItemData("PRDCODE01", "TEST PRODUCT") TB1.DataContext = item End Sub

对应的XAML代码如下:

<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Name="MainWindow" Loaded="MainWindow_Loaded" Title="MainWindow" Height="111.194" Width="295.149"> <TextBox Name="TB1" Text="{Binding Code}" HorizontalAlignment="Left" Height="22" VerticalAlignment="Top" Width="248" /> </Window>

在这个例子中,在TextBox的Text属性中使用了更简洁的语法。没有处理数据的双向性,只关注Code属性,而没有提到它必须从哪个元素(或DataContext)派生。这是因为DataContext是在代码端指定的,通过初始化ItemData类型的变量,然后将其作为TextBox的数据上下文。运行这个示例,会发现TextBox显示的值等于PR_CODE_01,即用来初始化ItemData的Code属性的字符串。

创建一个简单的ViewModel

ViewModel封装了一个模型,暴露了所有对视图有用的属性,以便访问底层数据。通常,它实现了INotifyPropertyChanged接口,该接口将作为事件使用,以跟踪特定属性的更改。在案例中,如果想要创建一个尽可能简单的ViewModel,可以编写如下的类:

Imports System.ComponentModel Public Class ItemDataView Implements INotifyPropertyChanged Dim item As New ItemData("PR_CODE_01", "TEST PRODUCT") Public Property Code As String Get Return item.Code End Get Set(value) If Not (item.Code = value) Then item.Code = value NotifyPropertyChanged("Code") End If End Set End Property Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private Sub NotifyPropertyChanged(Optional ByVal propertyName As String = Nothing) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) End Sub End Class

这个类初始化了一个ItemData,创建了它的一个新实例,并暴露了它的Code属性。同时,它允许修改该属性,并触发PropertyChanged事件,以通知发生的更改。

要使ItemDataView在整个MainWindow上下文中可见和可用,可以在窗口的XAML中将DataContext指定为全局,包含在其中的控件。TextBox的Binding属性将继续是Code,由ViewModel公开:

<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Name="MainWindow" Title="MainWindow" Height="111.194" Width="295.149"> <Window.DataContext> <local:ItemDataView x:Name="MyItemView" /> </Window.DataContext> <TextBox Name="TB1" Text="{Binding Code}" HorizontalAlignment="Left" Height="22" VerticalAlignment="Top" Width="248" /> </Window>

或者,如果希望指定特定的TextBox DataContext,可以这样写:

<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Name="MainWindow" Title="MainWindow" Height="111.194" Width="295.149"> <TextBox Name="TB1" DataContext="{Binding Source=ItemDataView}" Text="{Binding Code}" HorizontalAlignment="Left" Height="22" VerticalAlignment="Top" Width="248" /> </Window>
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485