Search code examples
c#winformsdata-bindingpathdatamember

Winforms data-binding: Period-delimited navigation path as DataMember causes exception. Why?


I keep having problems with Winforms data-binding, more specifically, whenever I specify a period-separated property path to be used as DataMember. For example:

public partial class SomeForm : System.Windows.Forms.Form
{
    public SomeForm(Book bookToBeDisplayed)
    {
        InitializeComponent();

        authorLabel.DataBindings.Add("Text", bookToBeDisplayed, "Author.Name");  
                                          // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                          //    I cannot get this to work.
    }
}


public class Book : INotifyPropertyChanged
{
    public Person Author { … }
    …
}

public class Person : INotifyPropertyChanged
{
    public string Name { … }
    …
}

The line where I'm adding a binding between authorLabel.Text and bookToBeDisplayed.Author.Name throws the following exception:

ArgumentException: Cannot bind to the property or column Name on the DataSource.

The "Remarks" section of the MSDN page about System.Windows.Forms.Binding explains that period-separated navigation paths can be used as DataMember:

You can also use a period-delimited navigation path when you bind to an object whose properties return references to other objects (such as a class with properties that return other class objects).

What do I have to do to make the above example work?

  • I've already made sure that the Book instance passed to SomeForm's constructor is properly initialized, and that there are no null references.
  • I also don't want to resort to DataSets.

Solution

  • I found a solution. Apparently, the DataSource must not be a single object, but a collection:

    authorLabel.DataBindings.Add("Text",
                                 new Book[] { bookToBeDisplayed },  // <--
                                 "Author.Name");
    

    The section "Types of Data Binding" of the MSDN page "Data Binding and Windows Forms" mentions that there are two types of data bindings: "simple" and "complex" ones. The latter binding type is also called "list-based binding". It seems that navigation paths are only supported with the latter binding type.

    P.S.: MSDN also recommends using BindingList<T>, though that's probably not necessary here.