数据绑定

实际开发中,界面控件的内容往往来自数据,例如对象、集合、数据库查询结果等,如果每次都手动把控件值和数据来回搬运,代码会既繁琐又容易出错。Winform内置了数据绑定机制,可以让控件和数据源自动保持同步。这篇笔记我们介绍Winform数据绑定的用法。

简单绑定

下面例子中,我们把输入框控件的Text属性绑定到数据对象的Name属性上了,这个绑定通过控件的DataBindings集合添加,绑定意味着:

  • 绑定建立的那一刻,输入框控件立刻加载1次绑定值
  • 用户在界面上编辑输入框控件后,默认在控件失去焦点时会把新值写入person对象
  • 不过注意此时修改person.Name,并不会自动刷新界面上控件的值,除非数据源实现了变更通知(后文介绍)
using Gacfox.Demo.Model;

namespace Gacfox.Demo;

public partial class TestForm : Form
{
    private readonly Student _student;
    public TestForm()
    {
        InitializeComponent();
        // 初始化student对象
        _student = new Student { Name = "John Doe", Age = 20 };
        // 绑定数据到控件
        nameTextBox.DataBindings.Add("Text", _student, "Name");
    }
}

如果希望修改数据对象后界面自动刷新,数据类需要实现INotifyPropertyChanged接口,并在属性变化时触发PropertyChanged事件。

using System.ComponentModel;

namespace Gacfox.Demo.Model;

public class Student : INotifyPropertyChanged
{
    private string? _name;
    public string? Name
    {
        get => _name;
        set
        {
            _name = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
        }
    }

    public int Age { get; set; }

    public event PropertyChangedEventHandler? PropertyChanged;
}

注意:对于绑定的列表数据源,普通的List<T>不支持变更通知,数据增删条目后界面不会刷新,Winform中应该使用BindingList<T>,它会在集合内容变化时自动通知绑定控件刷新。

使用BindingSource绑定

BindingSource是Winform数据绑定的中间适配器,它位于控件和真实数据源之间,它本身不存业务数据,只是相当于一层中介和代理,统一提供当前记录、导航、增删、排序、筛选等能力。BindingSource的意义在于它把五花八门的数据源统一成一套接口,控件只跟BindingSource打交道,不直接碰数据源对象,这样有利于代码的解耦合。实际开发中,更推荐的做法是把控件绑定到BindingSource,再把BindingSource.DataSource指向真实数据,而不是把控件直接绑到数据对象上。

BindingSource常用成员如下表格。

成员 说明
DataSource 数据源
Current 当前记录
Position 当前记录索引,修改它即可切换当前行
MoveFirst() / MoveNext() 导航方法
AddNew() / RemoveCurrent() 新增 / 删除当前记录
EndEdit() / CancelEdit() 结束 / 取消当前编辑
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。