Tuesday 5 May 2009

Reflection - Getting WinForm controls that implement a certain interface

I'm writing some code today for a compact framework application that will be used to help me do two-way databinding. On each form I want to dynamically invoke the databinding methods on each usercontrol that is involved with databinding. To do this I have defined an interface called IDataBoundControl which I want to use to identify controls that are involved with databinding. I use reflection to find these controls then add them to a collection of objects. Then I can just iterate around that collection and invoke the databinding methods on each control, thus calling their databinding methods.

public ArrayList GetDataBoundControls()
{
// Get the type of the current Win Form
Type t = this.GetType();
// This is the interface we want to use to find the controls
Type interfaceType = typeof(IDataBoundControl);
ArrayList databoundControls = new ArrayList();

// Get all the private fields
FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);

// Loop through each field
foreach (FieldInfo fi in fields)
{
  // Check that it's a UserControl so we don't waste time with it in case it isn't
  if (fi.FieldType.IsSubclassOf(typeof(UserControl)))
  {
    // Loop through the interfaces that the type implements
    foreach (Type it in fi.FieldType.GetInterfaces())
    {
      // If it implements the IDataBoundControl interface
      if (string.Compare(it.Name, interfaceType.Name,
        StringComparison.OrdinalIgnoreCase) == 0)
      {
        // Then get the object itself
        object control = fi.GetValue(this);

        // And add it to the ArrayList of databound controls for this form
        dataBoundControls.Add(control);
      }
    }
  }
}
}