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.... 🙂



Comments (4)
  1. Jan Tielens says:


    I’ve solved this issue too! If you are intrested in my approach, you can find the code here: http://www.codeproject.com/vb/net/leaditwebservicewrapper.asp

    It’s quite similar, I use reflection too, but I create a new type at runtime using CodeDom that wraps objects.



  2. Yura2000 says:


    As I can see BindingHelper returns as result static data structure.

    Is it really worth, from performance point of view?

    U use Web service. Next – u run with reflection(!!) on the result class and aftre it u wrap it into your class.

    Each action in this list not the fastest action.

    And what about the all together?

    Fix me, if there is mistake.

  3. Addy Santo says:

    Hi Yuri!

    Nice to know you still read my posts even though it has been – what – 9 months already ?!?!?

    Regarding the performance- We need to calling the webservice in any case, so that is a given. And the reflection is also a must (since the same class must be able to dynamically handle multiple data structures). The main question is when & where should it use caching and/or code generation to improve perf.

    The code currently recieves the data structure in the constructor, extracts the metadata via reflection, and caches it. This happens once per instance of the wrapper class, regardless of the number of data members or calls to the wrapper. Each subsequent call to a field is translated into a GetValue/SetValue invoke on the cached MemberInfo. While these calls are roughly x10 times slower than direct calls, my dev box still goes through several MILLION of them per second.

    The downside is that it isn’t possible to reuse the same wrapper instance, since the initialization is done in the ctor. This could easily be changed but it has not been an issue for me yet. Another possible improvement would be to use code generation to create native calls instead of going through GetValue/SetValue. This would substantially increase the init time but improve the per-call performance. Again, I have not yet felt the need to go that far.

    I already cleaned up the code, I can email it to you if want. Sometime this week (maybe!) I’ll wrap the code with an article and post it.

    Keep in touch!

  4. Yura2000 says:


    Sure, I keep eye persistently on your posts( and few more guys – Roy Osherov too).

    I’ll be very glad to get your code.

    I spend now lot of time on multithreading problems(bottlenecks and pools)

    There is my email(for case you don’t have one)



Comments are closed.

Skip to main content