C# Windows窗体数据绑定

C# Windows窗体数据绑定,c#,winforms,data-binding,solid-principles,C#,Winforms,Data Binding,Solid Principles,所以,我的问题是关于windows窗体数据绑定背后的确切方法 我编写了一个简单的代码,其中创建了一个视图、一个IViewModel接口和一个ViewModel interface IVM { } 及 该表单如下所示: public partial class Form1 : Form { private IVM vm; public Form1() { InitializeComponent(); this.vm = new Vm();

所以,我的问题是关于windows窗体数据绑定背后的确切方法

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

interface IVM
{
}

该表单如下所示:

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”写入文本框的测试属性,以绑定它

我的问题是,绑定到底是如何工作的?为什么我在尝试访问IVM的not existing Number属性时没有收到运行时错误? (我测试过,它实际上正确地更改了虚拟机的数字)

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


谢谢你的回答

Jup这是通过反射完成的。我刚刚检查了代码,绑定是由
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
}
if(this.control!=null&&this.propertyName.Length>0)
{
//…某些支票。。。
//get PropertyDescriptorCollection(所有属性)
for(int index=0;index
如Ike所述,您可以在此处找到源代码:


MSDN参考:

正如derape已经提到的,
绑定使用反射。它必须使用反射,因为它不能知道有关您正在使用的类的任何信息。评估将在运行时完成。由于您的具体类型
Vm
获得了指定的属性
Number
,反射将返回该属性,并满足
绑定
类。只要属性名有效,绑定就非常灵活

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


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

反射中派生,我相信。还有一些用于通知更改的支持事件(您的属性没有引发,因此您的绑定是一次性的)。我知道,我不关心这次InotifyProperty的更改,只是想知道它是如何工作的。您可以找到
Bindig
@ike的源代码谢谢,我将其添加到了回答中谢谢,这是一个非常好的回答。接受。我不想使用concere类型,因为我想在将来实现依赖倒置原则。我将把数字发布为接口道具。谢谢你的回答!
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
}