Enhancing winforms databinding to support fields as well as properties

Yes! It's 3am and my databound grid just came up. I'm very happy with the results, here's why:

The databinding mechanism in winforms does not support binding to fields. Meaning the following class will not work with any of the .NET databound controls:

public class myData
public int i;
public string s;

This is usually no more than an inconvience, and it is a better programming practice to use properties anyway. But when working with web services, the client side proxy classes generated by VS always contain fields (not properties). So basically, it is impossible to use data-binding with classes recieved from a webservice. 

There are several workarounds, the most common being to inherit the auto-generated class and add in the child class the needed properties. A less robust possibility is to manually create the proxy (using the WSDL.EXE command line) and modify the output class file, but obviously every interface change would invalidate the changes. I wanted to find a better way.

The first thing I tried was to change the way that the proxy class is created. A quick decompile of WSDL.EXE showed that it is a very thin wrapper (which basically just parses the command line) and all the real work is done inside BCL classes. Since all of the relevant classes are SEALED, that approach was a dead end. 

The next attempt was from the opposite side - given a standard .NET proxy client class, what was missing in order for databinding to work? According to the docs, the complex binding controls (grid, etc) require an IList. While an IList doesn't throw an exception, it doesn't exactly work either: a datagrid bound to string[ ] {”a”,”b”,”c”} comes up with “1,2,3“ as row values, and binding to a myData[ ] (see sample class above) will result in 0 columns being displayed.

So to really get jiggy with the datagrid, we need to supply it with an ITypedList. An ITypedList is the interface which allows the CurrencyManager to query the data structure for metadata describing the internal structure- fields, datatypes, read-only or not, etc. The implementation is fairly straightforward but almost totally undocumented, especially the logic for processing PropertyDescriptors. I finally decompiled and traced through how the System.Data.DataColumnPropertyDescriptor is used. After understanding the internal voodoo, the actual solution was simple:

I created a “BindingHelper“ class which receives an IList in the constructor, and dynamically wraps it with an ITypedList. The ITypedList discovers the internal data structure using reflection as needed and reports it to the calling controls. Simple!

So instead of the original syntax which bombed:
MyClass[] data = GetDataFromWS();
MyGrid.DataSource = data;
There is a new almost-as-friendly syntax:
MyClass[] data = GetDataFromWS();
MyGrid.DataSource = new BindingHelper(data);

And now I can call web services, get back data objects, display and update them in a data-bound client app, and post them back to the webservice, all in about 5 lines of code. Sweet!

I'll post the code after I clean it up a bit... right now it looks almost as if it was written during a hurricane at 3am by someone who had a few beers too many, I wonder why.... :)