• 通过Demo学WPF—数据绑定(一)✨


    前言✨

    想学习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,有两处地方,分别是:

      
          
              
          
      
    

     
    

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

     
          
              
          
      
    

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

    
    

    这种使用的是标记扩展

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

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

    先来看下Source

    image-20240129144554369

    我们发现这个demo里,Source="{StaticResource MyDataSource}StaticResource MyDataSource又是什么呢?

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

    image-20240129144901173

    
    

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

    这行代码创建了一个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 每当绑定目标属性发生更改时,都会更新绑定源。
     
     
         
             
         
     
    

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

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

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

    属性名 含义
    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的三个属性SourcePathUpdateSourceTrigger的含义,明白了数据源为什么要实现INotifyPropertyChanged接口,学会了WPF中数据绑定的基本用法,希望对你有所帮助。

  • 相关阅读:
    Linux篇【4】:Git,Gitee,GitHub
    欢迎 Stable Diffusion 3 加入 Diffusers
    OpenCV之油画特效
    递归组装树结构的数据
    R语言【base】——abs(),sqrt():杂项数学函数
    6.函数参数默认值的应用
    H2数据库端口占用
    前端中间件Midway的使用
    【01】ES6:ECMAScript 介绍
    vue和react区别?
  • 原文地址:https://www.cnblogs.com/mingupupu/p/17994859