Krisztián Kis
Krisztián Kis

Reputation: 68

Windows Forms data binding

So, my question is about the exact methodology behind windows form data binding.

I wrote a simple code, where i created a View, an IViewModel interface and a ViewModel.

interface IVM
{
}

and

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

        set
        {
            this.number = value;
        }
    }
}

the form looks like:

public partial class Form1 : Form
{
    private IVM vm;

    public Form1()
    {
        InitializeComponent();
        this.vm = new Vm();

        this.iVMBindingSource.DataSource = this.vm;
    }
}

and the related designer part is:

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

You can clearly see that IViewModel interface does not publish a Number property, but the concrete ViewModel class has a Number property.

Although in design time i can't use the designer to bind the property (since IVM has no Number prop), i can manually write "iVMBindingSource - Number" into the textbox's Test property, to bind it.

My question is, how does binding work EXACTLY? Why don't I receive a runtime error, while trying to access IVM's not existing Number property? (I tested and it actually changes the VM's Number prop properly)

Does it use some kind of reflection? How does this "magic" binding string works?

Thanks for your answers!

Upvotes: 1

Views: 554

Answers (2)

DerApe
DerApe

Reputation: 3175

Jup it's done by reflection. I just checked the code and the binding is done by the Binding class. There is a method called CheckBindings which ensures the property you want to bind on is available. It basically works like this:

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
}

As Ike mentioned, you can find the source code here: http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Binding.cs,3fb776d540d0e8ac

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

Upvotes: 3

Bastian Thiede
Bastian Thiede

Reputation: 468

As derape already mentioned, Binding uses reflection. It must use reflection because it cannot know anything about the class you are using. The evaluation will be done at runtime. Since your concrete type Vm got the specified property Number, reflection will return it and Binding class is satisfied. Binding is really flexible as long as the property name is valid.

On the other hand, when you are using the designer, it cannot know which concrete type you will use. Therefore it only allows you to use properties of the common base IVM. If you enter the string manually, design time evaluation will be skipped and input is passed to the binding constructor.

If you want to use designer support, just use the the concrete type or if you don't know the concrete type but need the property Number, simply create a new interface and derive from IMV.

Upvotes: 0

Related Questions