Windows 表单数据绑定

Windows Forms data binding

所以,我的问题是关于 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属性,但是具体的ViewModelclass有一个Number属性.

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

我的问题是,绑定究竟是如何工作的?为什么我在尝试访问 IVM 不存在的编号 属性 时没有收到运行时错误? (我测试过,它实际上正确地改变了 VM 的 Number 属性)

它使用某种反射吗? "magic" 绑定字符串如何工作?

感谢您的回答!

Jup 这是通过反射完成的。我刚刚检查了代码,绑定是由 Binding class 完成的。有一种名为 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/Managed/System/WinForms/Binding.cs,3fb776d540d0e8ac

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

正如 derape 已经提到的,Binding 使用反射。它必须使用反射,因为它无法了解您正在使用的 class 的任何信息。评估将在运行时完成。由于您的具体类型 Vm 得到指定的 属性 Number,反射将 return 它并且 Binding class 得到满足。只要 属性 名称有效,绑定就非常灵活。

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

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

派生