Synchronising the WinForm data binding using .NET 2.0

The new implemented data binding functionality for .NET 2.0 seems to be quite useful. But there is one pitfall I fell in yesterday.

Normally the datasource will be updated immediatly when leaving the focus of the bound control. Yesterday I had the following scenario.

The problem:
When clicking the OK button the bound object will be verified and than stored to database. Thats the theory. Mostly this worked fine, except few times when I left the focus of an control using the TAB key. In that case sometimes the data hadn’t been bound to the data source.

After debugging I came to the conclusion that this must be a problem of asynchron events which are responsible for writing the changed data back to the data source. I’m thinking this way because the problem hit me unsteady and most time not when I was using the debugger.

private void OnLoad(object sender, EventArgs e)
{
  dateBinding.DataSource = dateClass;
}

The solution:
In the MSDN documentation I found the method BindingSource.EndEdit(). Ahh! That was the missing link I was looking for. Using this method I could force the DataSource to be updated by the WinForm.

private void OnOkButton_Click(object sender, EventArgs e)
{
  dateBinding.EndEdit();
  // do your validations here
}

Important:
The EndEdit() method does not work without any changes to other parts of the source code.

The DataSource has to implement the IEditableObject interface. You don’t have to do anything within the methods BeginEdit, CancelEdit or EndEdit. But the interface is important for the BindingSource, because it forces an deferred data binding which writes the data only back when calling the EndEdit Method.

class DateClass : IEditableObject
{
  #region IEditableObject Members

  public void BeginEdit()
  {
  }

  public void CancelEdit()
  {
  }

  public void EndEdit()
  {
  }

  #endregion

  #region Properties
  #endregion
}

Conclusion:
Even if you do not have the problems with the data binding that I had, I would recommend to use the data binding mentioned above.

Implementing the IEditableObject and using the EndEdit() method is the most safe way to implement the databinding functionality of .NET 2.0. That is because you always know the state of your datasource and you have the ability to control the state of the data.

Addendum – 2 days later
I have to apologize to Microsoft, because it was’nt their fault – I found the bug. The problem was that I bound one data field by mistake to two UI controls. This caused unpredictable results when writing the results back to the data object every time the control lost or got the focus. That’s why my second solution (explained above) solved the problem, because I had one defined write-back point in my code.

Anyway – what did I learn?

  1. It’s better to control the data binding first if you make strange observations on your data binding.
  2. Having one defined write-back point can help you to reproduce the wrongdoing of your application more easy.

Any suggestions to this are welcome.

Copying a native untyped IList to a generic List

For compatibility reasons there are still libraries and components which do not use the new generics offered by Visual Studio 2005. This should be no problem as long as you want to use these native collections. But if you need a type safe result list you have to copy all elements one by one to your new generic List.

IList<string> genericList = new List<string>();
foreach (string str in myNativeList)
   genericList.Add (str);

Stop! Didn’t we thought that we don’t have to do stupid hand-crafted copy jobs? Yes, but dotNET 2.0 does not offer a quick solution. That is because the new generic List won’t offer an interface that allows you to put in the old IList interface. So let us take a look at the constructor of a generic List.

public List (
  IEnumerable<T> collection
)

The idea is to create an adapter that offers the IEnumerable<T> interface in order to allow quick copying the native collection to a generic list. I call it a ListAdapter.

Using this ListAdapter you can convert native collections easily to their generic counterparts without any external copy operations.

IList<string> genericList = new List<string> (
  new ListAdapter<string> (myNativeList)
);

You can download the implementation of the ListAdapter using the following link:
Copying a native untyped IList to a generic List

Hope that this piece of code makes your life easier.
Cheers
Gerhard

PS: At this place I won’t forget to say thanks to Mr. Alexander Jung for his idea to the ListAdapter :)