Functional WinForms (or Generic Control Creation 2)


Continuing on this mental exercise that I started in my last post. In this post I started throwing some ideas on how we can utilize the features of C# 3.0 language enhancements (or how it’s fashionable to call it now “functional programming”) in the way we handle WinForms. Here is another idea – what if we could delay the control creation and initialization until the time is right, but having all the initialization code already prepared and ready to fire (This should be really useful on the devices considering the performance and memory hit we get when the form is created)? The answer is -  of course we can! The delayed execution functionality simply comes for free with the usage of the lambda expressions. Remember that last time we could create an instance of the control and initilialize its properties by using the extension method AddControl. This time around I've added another extension method which is called InitControl. Imagine that we'll have the code that prepares the control's creation: 


// Initialize label


this.InitControl<Label>(() => new Label


{


        Name = "labelHello",


        Location = new Point(50, 100),


}, "labelHello");


// Initialize button


this.InitControl<Button>(() => new Button()


{


     Name = "button",


     Text = "Click Me 2",


     Location = new Point(50, 150),


     Font = this.Font,                               


 }.AddHandler<Button>("Click", new EventHandler(clickButton_Click))


  .AddHandler<Button>("KeyPress", new KeyPressEventHandler(clickButton_Click)),


"button");


Notice how in the code above we can also add an event handlers for the button's Click event. And since it's going to be a part of lambda expression it will not be executed immediatedly. Now after we are done with init logic we can build these instances in one swoop:


this.BuildAll();


Or we can create them explicitly:


this.Build<Label>("labelHello");


 


this.Build<Button>("button");



Wondering how's that all done? Consider these extension methods:


// Capture control creation delegate


public static Func<Control> InitControl<T>(this Control parent,


                      Func<Control> build, string key) where T : Control


{


      if (buildList == null)


      {


           buildList = new Dictionary<string, Func<Control>>();


      }


           


      // Add the control creation delegate to the dictionary


      buildList.Add(key, build);


      return build;


}


// Add event handler for a named event.


public static T AddHandler<T>(this Control control,


string eventName, Delegate handler) where T : Control


{


       EventInfo eventInfo = control.GetType().GetEvent(eventName);


       eventInfo.AddEventHandler(control, handler);


       return control as T;


}


// Create instances for all captured control creating delegates


public static void BuildAll(this Control parent)


{


      if (buildList == null)


      {


           throw new ArgumentNullException("The build list is null.");


      }


      // Iterate, create instances and add to controls collection


      foreach (Func<Control> build in buildList.Values)


      {               


           parent.Controls.Add(build());


      }


      // Remove the delegates from the dictionary


      buildList.Clear();


}


 


// Build a particular control


public static T Build<T>(this Control parent, string key) where T : Control


{


      if (buildList == null)


      {


          throw new ArgumentNullException("The build list is null.");


      }


 


      // Create control's instance


      Control control = buildList[key]();


      // Remove delegate from the list


      buildList.Remove(key);


      // Add to the controls' collection


      parent.Controls.Add(control);


      return control as T;


}


The code above should be self descriptive enough. You can download the new version of the ControlExtension class from here.


As usual the comments are welcome in any form. Just let me know if I am crazy 🙂


 

ControlExtension.cs

Comments (2)
  1. Since posting a few of my last ideas , my brain has been running a few background threads on how else

  2. mahesh says:

    really helpful to know about winforms

    <a href="http://dapfor.com&quot; target=new>winforms</a>

Comments are closed.

Skip to main content