如何创建数据绑定

本文介绍如何创建绑定 XAML。 该示例使用表示公司员工的数据对象。 此数据对象绑定到 XAML 窗口,该窗口使用 TextBlock 控件列出员工的详细信息。 你将创建如下图所示的 UI:

一个 WPF 窗口,显示有关员工的详细信息,例如其名字、姓氏、职务、雇佣日期和工资。

若要了解有关数据绑定的详细信息,请参阅 WPF 中的数据绑定概述

创建数据对象

在此示例中,员工用作 UI 绑定到的数据对象。

  1. 向项目添加新类并将其命名 Employee

  2. 将所有代码替换为以下片段:

    using System;
    using System.ComponentModel;
    
    namespace ArticleSample
    {
        public class Employee : INotifyPropertyChanged
        {
            private decimal _salary;
            public event PropertyChangedEventHandler? PropertyChanged;
    
            public required string FirstName { get; set; }
            public required string LastName { get; set; }
            public required string Title { get; set; }
            public required DateTime HireDate { get; set; }
    
            public required decimal Salary
            {
                get => _salary;
                set
                {
                    _salary = value;
    
                    // Support TwoWay binding
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Salary)));
                }
            }
        }
    }
    
    Imports System.ComponentModel
    
    Public Class Employee
        Implements INotifyPropertyChanged
    
        Private _salary As Decimal
        Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    
        Public Property FirstName As String
        Public Property LastName As String
        Public Property Title As String
        Public Property HireDate As DateTime
    
        Public Property Salary As Decimal
            Get
                Return _salary
            End Get
            Set(value As Decimal)
                _salary = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(Salary)))
            End Set
        End Property
    
    End Class
    

员工数据对象是描述员工的简单类:

  • 员工的名字和姓氏。
  • 员工被雇用的日期。
  • 员工的公司职务。
  • 员工的收入。

绑定到数据对象

以下 XAML 演示如何将 Employee 类用作数据对象。 根元素 DataContext 的属性绑定到 XAML 中声明的静态资源。 各个控件绑定到 Employee 的属性。

  1. 向项目添加新 窗口 并将其命名 EmployeeView

  2. 将 XAML 替换为以下代码片段:

    重要

    以下代码片段取自 C# 项目。 如果使用 Visual Basic,则应声明 x:Class 而不使用 ArticleSample 命名空间。 您可以在 EmployeeView.xaml 上查看 Visual Basic 版本的外观。

    <Window x:Class="ArticleSample.EmployeeView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:ArticleSample"
            Title="" Height="250" Width="300">
        <Window.Resources>
            <local:Employee x:Key="EmployeeExample" FirstName="Niki" LastName="Demetriou"
                                                    HireDate="2022-02-16" Salary="5012.00"
                                                    Title="Content Artist" />
        </Window.Resources>
        <StackPanel DataContext="{StaticResource EmployeeExample}">
            <Label FontSize="32">Employee</Label>
            <Border BorderBrush="Gray" BorderThickness="2" />
            <Grid Grid.Row="1" Margin="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
    
                <TextBlock Text="First Name:" Grid.Row="0" Margin="0,0,10,0" />
                <TextBlock Text="Last Name:" Grid.Row="1" />
                <TextBlock Text="Title:" Grid.Row="2" />
                <TextBlock Text="Hire Date:" Grid.Row="3" />
                <TextBlock Text="Salary" Grid.Row="4" />
    
                <TextBlock Text="{Binding FirstName}" Grid.Row="0" Grid.Column="1" />
                <TextBlock Text="{Binding LastName}" Grid.Row="1" Grid.Column="1" />
                <TextBlock Text="{Binding Title}" Grid.Row="2" Grid.Column="1" />
                <TextBlock Text="{Binding HireDate, StringFormat=d}" Grid.Row="3" Grid.Column="1" />
                <TextBlock Text="{Binding Salary, StringFormat=C0}" Grid.Row="4" Grid.Column="1" />
            </Grid>
            <Border BorderBrush="Gray" BorderThickness="2" />
            
            <StackPanel Margin="5,10" Orientation="Horizontal">
                <TextBlock Text="Change Salary:" Margin="0,0,10,0" />
                <TextBox Text="{Binding Salary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat=C0}" Width="100" />
            </StackPanel>
        </StackPanel>
    </Window>
    

除非创建了名为 ArticleSample 的项目,否则代码的命名空间与项目的命名空间不匹配。 如果创建了一个新项目,则可以将 Window.Resources 和根元素 (StackPanel) 复制并粘贴到 MainWindow 中。

若要更好地了解上一个 XAML 如何使用数据绑定,请考虑以下几点:

  • XAML 资源用于创建类的 Employee 实例。

    通常,数据对象将传递给窗口或与之关联的对象。 此示例将员工硬编码为演示目的。

    <Window.Resources>
        <local:Employee x:Key="EmployeeExample" FirstName="Niki" LastName="Demetriou"
                                                HireDate="2022-02-16" Salary="5012.00"
                                                Title="Content Artist" />
    </Window.Resources>
    
  • 根元素 (StackPanel) 将其数据上下文设置为硬编码 Employee 实例。

    子元素继承父元素的 DataContext,除非进行了显式设置。

    <StackPanel DataContext="{StaticResource EmployeeExample}">
    
  • 实例的属性 Employee 绑定到 TextBlock 控件。

    Binding未指定一个BindingSource,因此用作DataContext源。

    <TextBlock Text="{Binding FirstName}" Grid.Row="0" Grid.Column="1" />
    <TextBlock Text="{Binding LastName}" Grid.Row="1" Grid.Column="1" />
    <TextBlock Text="{Binding Title}" Grid.Row="2" Grid.Column="1" />
    <TextBlock Text="{Binding HireDate, StringFormat=d}" Grid.Row="3" Grid.Column="1" />
    <TextBlock Text="{Binding Salary, StringFormat=C0}" Grid.Row="4" Grid.Column="1" />
    
  • TextBox控件与TwoWay模式绑定,允许TextBox更改Employee.Salary属性。

    <TextBox Text="{Binding Salary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat=C0}" Width="100" />