前言✨

想学习WPF,但是看视频教程觉得太耗时间,直接看文档又觉得似懂非懂,因此想通过看Demo代码+文档的方式进行学习。

准备✨

微软官方其实提供了WPF的一些Demo,地址为:
microsoft/WPF-Samples: Repository for WPF related samples (github.com)

将其克隆到本地,有很多的Demo代码:

image-20240129141054183

新建一个空白解决方案:

image-20240129141201234

添加现有项目:

image-20240129141238024

选择Data Binding 中的 SimpleBinding:

image-20240129141537501

项目文件如下所示:

image-20240129141951318

查看SimpleBinding这个Demo的效果:

SimpleBindingDemo的效果

学习这个Demo✨

数据绑定的概念

首先需要知道数据绑定的基本概念,数据绑定是在应用 UI 与其显示的数据之间建立连接的过程。 如果绑定具有正确的设置,并且数据提供适当的通知,则在数据更改其值时,绑定到该数据的元素会自动反映更改。 数据绑定还意味着,如果元素中数据的外部表示形式发生更改,则基础数据可以自动进行更新以反映更改。 例如,如果用户编辑
TextBox
元素中的值,则基础数据值会自动更新以反映该更改。

现在再来看一下,数据绑定的模型图:

image-20240129142805099

现在我们根据这张模型图,学习这个Demo。

这个模型图表示数据绑定至少需要三个东西:

  • 绑定目标
  • 绑定
  • 绑定源

现在我们分别看看这个demo里面,这三个东西在哪?

绑定目标

我们发现这个demo的绑定目标是元素TextBox的Text属性与TextBlock的Text属性。

绑定

image-20240129143549091

这是一个C#类,查找在该Demo中,哪里出现了Binding?

发现在MainWindow.xaml中出现了Binding,有两处地方,分别是:

  <TextBox>
      <TextBox.Text>
          <Binding Source="{StaticResource MyDataSource}" Path="PersonName"
 UpdateSourceTrigger="PropertyChanged"/>
      </TextBox.Text>
  </TextBox>

 <TextBlock Text="{Binding Source={StaticResource MyDataSource}, Path=PersonName}"/>

这两处都是在 XAML 中声明绑定。

 <TextBox>
      <TextBox.Text>
          <Binding Source="{StaticResource MyDataSource}" Path="PersonName"
 UpdateSourceTrigger="PropertyChanged"/>
      </TextBox.Text>
  </TextBox>

这种使用的是
对象元素语法

<TextBlock Text="{Binding Source={StaticResource MyDataSource}, Path=PersonName}"/>

这种使用的是
标记扩展

从这里我们接触到了
Binding
类的三个属性,
Source

Path

UpdateSourceTrigger

那它们分别是什么意思呢?

先来看下
Source

image-20240129144554369

我们发现这个demo里,
Source="{StaticResource MyDataSource}

StaticResource MyDataSource
又是什么呢?

在Window.Resources标签下有一行代码:

image-20240129144901173

<local:Person x:Key="MyDataSource" PersonName="Joe"/>

<Window.Resources>
标签在XAML中用于定义可以在整个窗口中重用的资源。这些资源可以是各种类型,包括样式、数据源、数据模板、颜色、画刷等。

<local:Person x:Key="MyDataSource" PersonName="Joe"/>
这行代码创建了一个Person对象,并将其命名为"MyDataSource",该对象的PersonName属性设置为"Joe",这样你就可以在窗口的其他地方通过这个键来引用这个对象。

因此
Source={StaticResource MyDataSource}
的意思就是将Binding对象的Source属性设置为键为"MyDataSource"的资源,在这里也就是一个Person对象。

再来看看
Path

image-20240129150048051

表示绑定源属性的路径。

Path="PersonName"
表示绑定源是刚刚那个Person对象的PersonName属性。

最后再看看
UpdateSourceTrigger

image-20240129150426493

这个属性可能就会难理解一点。

它表示当绑定目标怎么样时,绑定源的值应该被更新。

它的类型为枚举类型,有以下几个值:

含义
Default 绑定目标属性的默认
UpdateSourceTrigger
值。 大多数依赖属性的默认值为
PropertyChanged
,而
Text
属性的默认值为
LostFocus
Explicit 仅在调用
UpdateSource()
方法时更新绑定源。
LostFocus 每当绑定目标元素失去焦点时,都会更新绑定源。
PropertyChanged 每当绑定目标属性发生更改时,都会更新绑定源。
 <Label>Enter a Name:</Label>
 <TextBox>
     <TextBox.Text>
         <Binding Source="{StaticResource MyDataSource}" Path="PersonName"
UpdateSourceTrigger="PropertyChanged"/>
     </TextBox.Text>
 </TextBox>

我们会发现在这个demo中,
TextBox.Text
设置了
UpdateSourceTrigger
属性。

这是因为大多数依赖项属性的默认值为
PropertyChanged
,而
Text
属性的默认值为
LostFocus
。在这个demo中,我们不希望失去焦点才更新源数据,而是一发生改变就更新绑定源,因此设置
UpdateSourceTrigger
属性为
PropertyChanged

总结一下,我们遇到的关于Binding类的三个属性
Source

Path

UpdateSourceTrigger

属性名 含义
Source 获取或设置要用作绑定源的对象。
Path 获取或设置绑定源属性的路径。
UpdateSourceTrigger 获取或设置一个值,它可确定绑定源更新的时机。

现在我们已经介绍了绑定目标、绑定就差绑定源了。

绑定源

在数据绑定中,绑定源对象是指用户从其获取数据的对象。

在这个demo中,绑定源是一个Person对象。

查看Person类的代码:

using System.ComponentModel;

namespace SimpleBinding
{
    // This class implements INotifyPropertyChanged
    // to support one-way and two-way bindings
    // (such that the UI element updates when the source
    // has been changed dynamically)
    public class Person : INotifyPropertyChanged
    {
        private string _name;

        public Person()
        {
        }

        public Person(string value)
        {
            _name = value;
        }

        public string PersonName
        {
            get { return _name; }
            set
            {
                _name = value;
                // Call OnPropertyChanged whenever the property is updated
                OnPropertyChanged("PersonName");
            }
        }

        // Declare the event
        public event PropertyChangedEventHandler PropertyChanged;
        // Create the OnPropertyChanged method to raise the event
        protected void OnPropertyChanged(string name)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

首先这个
Person
类实现了
INotifyPropertyChanged
接口,我们来看下
INotifyPropertyChanged
接口:

public interface INotifyPropertyChanged
{
    //
    // 摘要:
    //     Occurs when a property value changes.
    event PropertyChangedEventHandler? PropertyChanged;
}

包含一个PropertyChanged事件,因此该Person类必须实现接口的成员PropertyChanged。

当属性值被设置时,会调用OnPropertyChanged方法,从而触发事件。

INotifyPropertyChanged
接口定义了一个
PropertyChanged
事件,当一个属性的值发生变化时,你可以触发这个事件。WPF的数据绑定引擎会监听这个事件,当事件被触发时,它会更新绑定的UI元素的值。
如果你的数据源没有实现这个接口,那么当数据源的属性值发生变化时,WPF的数据绑定引擎将无法知道这个变化,因此它将无法更新UI元素的值。
这意味着,如果你的数据源的属性值在运行时可能会发生变化,并且你希望这些变化能够自动反映到UI上,那么你的数据源就需要实现
INotifyPropertyChanged
接口。

总结✨

通过这个小Demo,我们明白了WPF中的数据绑定的三要素,绑定对象、绑定、绑定源。在这个demo中,我们学会了如何在xaml中声明绑定,知道了Binding的三个属性
Source

Path

UpdateSourceTrigger
的含义,明白了数据源为什么要实现
INotifyPropertyChanged
接口,学会了WPF中数据绑定的基本用法,希望对你有所帮助。

标签: none

添加新评论