Windows窗体数据绑定

本文关键字:数据绑定 窗体 Windows | 更新日期: 2023-09-27 18:03:15

那么,我的问题是关于windows表单数据绑定背后的确切方法。

我写了一个简单的代码,其中我创建了一个视图,一个IViewModel接口和一个ViewModel。

interface IVM
{
}

public class Vm : IVM
{
    int number;
    public int Number
    {
        get
        {
            return this.number;
        }
        set
        {
            this.number = value;
        }
    }
}

格式如下:

public partial class Form1 : Form
{
    private IVM vm;
    public Form1()
    {
        InitializeComponent();
        this.vm = new Vm();
        this.iVMBindingSource.DataSource = this.vm;
    }
}

,相关设计部分为:

this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.iVMBindingSource, "Number", true));
...
this.iVMBindingSource.DataSource = typeof(WindowsFormsApplication1.IVM);

你可以清楚地看到IViewModel接口没有发布Number属性,但是具体的ViewModel类有一个Number属性。

虽然在设计时我不能使用设计器来绑定属性(因为IVM没有数字道具),我可以手动将"iVMBindingSource - Number"写入文本框的Test属性,来绑定它。

我的问题是,绑定到底是如何工作的?为什么我没有收到一个运行时错误,而试图访问IVM的不存在的数字属性?(我测试了,它实际上改变了VM的数字道具正确)

它使用某种反射吗?这个"神奇"的绑定字符串是如何工作的?

谢谢你的回答!

Windows窗体数据绑定

这是通过反射完成的。我刚刚检查了代码,绑定是由Binding类完成的。有一个名为CheckBindings的方法可以确保您想要绑定的属性是可用的。它基本上是这样工作的:

if (this.control != null && this.propertyName.Length > 0)
{
  // ...certain checks...
  // get PropertyDescriptorCollection (all properties)
  for (int index = 0; index < descriptorCollection.Count; ++index)
  {
    // select the descriptor for the requested property
  }
  // validation
  // setup binding
}

正如Ike提到的,你可以在这里找到源代码:http://referencesource.microsoft.com/System.Windows.Forms winforms/管理/系统/winforms/Binding.cs, 3 fb776d540d0e8ac

MSDN参考:https://msdn.microsoft.com/en-us/library/system.windows.forms.binding(v=vs.110).aspx

如前所述,Binding使用反射。它必须使用反射,因为它无法知道您正在使用的类的任何信息。评估将在运行时完成。由于您的具体类型Vm获得了指定的属性Number,反射将返回它并且Binding类满足。只要属性名有效,绑定是非常灵活的。

另一方面,当您使用设计器时,它无法知道您将使用哪种具体类型。因此,它只允许您使用公共基数IVM的属性。如果手动输入字符串,将跳过设计时评估,并将输入传递给绑定构造函数。

如果您想使用设计器支持,只需使用具体类型,或者如果您不知道具体类型,但需要属性Number,只需创建一个新的接口并从IMV派生。