Winform 中实现控件与数据的绑定,一方改变另一方同步改变。
1. 目的
用 Winform 想实现控件与后台数据的解耦,但是同样可以做到控件的显示改变时,后台数据同步改变;后台数据修改,控件则同步刷新。
2. 下载引用库
CommunityToolKit.Mvvm
代码中:using CommunityToolkit.Mvvm.ComponentModel;
3. 界面
4. 实现与界面对应的后台数据
创建一个类 ObservableText,要继承 ObservableObject,里面的属性才可以用到 MVVM 的属性变更通知的核心方法 SetProperty。
定义与控件参数绑定的属性:
Input 的Text:TextValue
Label 的 Text:LabelText
ComboBox 的当前 Index:CcbIndex
控件 | 控件属性 | 后台类属性 |
Input | Text | TextValue |
Label | Text | LabelText |
ComboBox | SelectedIndex | CcbIndex |
5. 实现绑定
使用 Control 类都提供的 DataBindings(控件的数据绑定集合),Add 函数:
public Binding Add(string propertyName, object dataSource, string dataMember)
例如 Label 的 Text 绑定:
//Label
lblText.DataBindings.Add("Text", _obserTxt, nameof(_obserTxt.LabelText));
6. 运行测试
(1)改变与控件绑定的后台数据,观察控件显示。
(2)改变控件显示信息,观察与之绑定的后台数据。
实际上都会改变,即一方改变,另一方同步改变。
7. 完整代码:
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Diagnostics;
using System.Windows.Forms;namespace WindowsFormsApp1
{public partial class Form1 : Form{ObservableText _obserTxt = new ObservableText();public Form1(){InitializeComponent();InitData();SetDataBindings();}private void SetDataBindings(){//TexttxtTest1.DataBindings.Add("Text", _obserTxt, nameof(_obserTxt.TextValue));//LabellblText.DataBindings.Add("Text", _obserTxt, nameof(_obserTxt.LabelText));//ComboBoxccb.DataBindings.Add("SelectedIndex", _obserTxt, nameof(_obserTxt.CcbIndex));}private void InitData(){ccb.Items.Add("Joe");ccb.Items.Add("Jake");ccb.Items.Add("Andy");}private void btnSetText_Click(object sender, EventArgs e){_obserTxt.TextValue += 11.4f;}private void btnSetLabel_Click(object sender, EventArgs e){_obserTxt.LabelText += " World";}private void btnSetComboBox_Click(object sender, EventArgs e){if (_obserTxt.CcbIndex < ccb.Items.Count - 1)_obserTxt.CcbIndex++;else_obserTxt.CcbIndex = 0;}private void btnTest_Click(object sender, EventArgs e){Debug.WriteLine("---------: " + _obserTxt.TextValue + "; " + _obserTxt.CcbIndex);}}public class ObservableText : ObservableObject{private float _textValue = 100.1f;private string _labelText = "Hello";private int _ccbIndex = 0;public float TextValue{get => _textValue;set => SetProperty(ref _textValue, value);}public string LabelText{get => _labelText;set => SetProperty(ref _labelText, value);}public int CcbIndex{get => _ccbIndex;set => SetProperty(ref _ccbIndex, value);}public ObservableText() { }}
}