Generic control creation.

I've been doing a lot of coding lately that utilize the features of the C# 2.0  and 3.0 language enhancements such as generics, Func delegates, anonymous types etc... And then it hit me that we are still using the old and clumsy coding style when developing for WinForms - creating controls, assinging properties etc...  What if we could do something like that:        

Button clickButton = this.AddControl<Button>(c => new Button()

{

       Name = "button",

       Text = "Click Me",

       Location = new Point(100, 200),

       Font = c.Font

});

 

In the code above we create an instance of the Button, set it's properties and add it to the parent's controls collection - all in one line of code! Do you like it? I do. Somehow it feels much cleaner and nicer than this:

  

Button clickButton = new Button();

clickButton.Name = "button";

clickButton.Text = "Click Me";

clickButton.Location = new Point(100, 200);

clickButton.Font = this.Font;

this.Controls.Add(clickButton); 

So here is how the code for the "Hello World" sample Form would look like:

 

public partial class Form1 : Form

{

    public Form1()

    {

        InitializeComponent();

        

        // Create button and add it to the Form's controls collection

        Button clickButton = this.AddControl<Button>(c => new Button()

        {

            Name = "button",

            Text = "Click Me",

            Location = new Point(100, 200),

            Font = c.Font

        });

        // Hook up into the click event

        clickButton.Click += new EventHandler(clickButton_Click);

        // Create label

        this.AddControl<Label>(c => new Label()

        {

            Name = "labelHello",

            Location = new Point(100, 240)

        });

         

    }

    void clickButton_Click(object sender, EventArgs e)

    {

        // Assign the value to the Text property of the label

  this.GetControl<Label>("labelHello").Text = "Hello world.";

    }

}

So what do we need to be able to write the code like this? All we need to do is to add the following ControlExtension class:

 

public static class ControlExtension

{

     public static T AddControl<T>(this Control parent,

Func<Control, T> build)

     {

         T control = build(parent);

         parent.Controls.Add(control as Control);

         return control;

     }

     public static Control GetControl(this Control parent, string name)

     {

         return parent.Controls[name];

     }

     public static T GetControl<T>(this Control parent, string name)

where T : Control

     {

         return parent.Controls[name] as T;

     }

 }

In this class all we do is just create a few extension methods for the Control. That's it folks.

 

And by the way, this code works on both desktop (.NET 3.5) and device side (.NET CF 3.5)

 

Enjoy :)