title: Binding custom properties' values of an instance of ExpandoObject to a .NET Windows Forms controls
body: <h2>Context: Visual Studo 2012/C# 5.0</h2>
  
  <p>I have a .NET Windows Form with three textbox controls: <em>firstNameTextBox</em>, <em>lastNameTextBox</em> and <em>ageTextBox</em>, and a simple custom class</p>
  
  <pre><code>public class Customer
  {
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int Age { get; set; }
  }
  </code></pre>
  
  <p>and I'd like to bind the properties of an instance of <em>Customer</em> custom class to my Windows Forms controls. So I write:</p>
  
  <pre><code>private dynamic _customer;
  private void Form_Load(object sender, EventArgs e)
  {
      _customer = new Customer()
      {
          FirstName = "Andrew",
          LastName = "Chandler",
          Age = 23
      };
      this.firstNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text",     _customer, "FirstName"));
      this.lastNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", _customer, "LastName"));
      this.ageTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", _customer, "Age"));
  }
  </code></pre>
  
  <p>and that works well. Then I slightly change the code by making it using an anonymous type:</p>
  
  <pre><code>private dynamic _customer;
  private void Form_Load(object sender, EventArgs e)
  {
      _customer = new 
      {
          FirstName = "Andrew",
          LastName = "Chandler",
          Age = 23
      };
      this.firstNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", _customer, "FirstName"));
      this.lastNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", _customer, "LastName"));
      this.ageTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", _customer, "Age"));
  </code></pre>
  
  <p>}</p>
  
  <p>and that also works rather well, although in this case I do have only one-way binding. Then I change my code even more:</p>
  
  <pre><code>private dynamic _customer;
  private void Form_Load(object sender, EventArgs e)
  {   
      _customer = new ExpandoObject();
      _customer.FirstName = "Andrew";
      _customer.LastName = "Chandler";
      _customer.Age = 23;
  
       this.firstNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", _customer, "FirstName"));
       this.lastNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", _customer, "LastName"));
       this.ageTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", _customer, "Age"));
  }
  </code></pre>
  
  <p>and I'm getting runtime error:</p>
  
  <p><strong>'Cannot bind to the property or column FirstName on the DataSource. Parameter name: dataMember'</strong></p>
  
  <p><strong>Question:</strong> How can I bind an instance of System.Dynamic.ExpandoObject (or System.Dynamic.DynamicObject) having a set of dynamic custom properties to a Windows Forms set of (textbox) controls? </p>
  
  <p><strong>Note 1:</strong> A solution with an aggregating/container helper class would be OK for me.</p>
  
  <p><strong>Note 2:</strong> I have spent a few hours googling and trying to apply different techniques (including the ones I have found here on StackOverflow) but I have failed.</p>
  
  <h2>Here is an 'Elegant' solution based on Hans Passant hint:</h2>
  
  <pre><code>private dynamic _customer;
  private void Form_Load(object sender, EventArgs e)
  {
      _customer = new ExpandoObject();
      _customer.FirstName = "Andrew";
      _customer.LastName = "Chandler";
      _customer.Age = 23;
  
      bindExpandoField(this, "FirstNameTextBox", "Text", _customer, "FirstName");
      bindExpandoField(this, "lastNameTextBox", "Text", _customer, "LastName");
      bindExpandoField(this, "ageTextBox", "Text", _customer, "Age");
  }
  
  
  private void bindExpandoField(
        Control hostControl,
        string targetControlName,
        string targetPropertyName,
        dynamic expandoObject,
        string sourcePropertyName)
  {
      Control targetControl = hostControl.Controls[targetControlName];
      var IDict = (IDictionary&lt;string, object&gt;)expandoObject;
      var bind = new Binding(targetPropertyName, expandoObject, null);
      bind.Format += (o, c) =&gt; c.Value = IDict[sourcePropertyName];
      bind.Parse += (o, c) =&gt; IDict[sourcePropertyName] = c.Value;
      targetControl.DataBindings.Add(bind);
  }
  </code></pre>