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 🙂

Comments (7)
  1. Regev says:

    Very neat, especially the AddControl extension! Though I would prefer to leave the controls declaration out of the form’s constructor instead of using the GetControl extension, so the compiler will be able to trace errors and for better performance.

    Interesting as always. Thx.

  2. Kevin Daly says:

    Hi Alex,

    Great stuff.

    I ran into a hitch with the Compact Framework with the WinForms implementation not providing a string indexer for Controls, so I used this instead(example from GetControl):

    return parent.Controls.OfType<Control>().SingleOrDefault(c => c.Name == name);

    That works OK for me but let me know if there’s another approach that’s preferred (I’m very partial to LINQ to Objects and likely to use/misuse it whenever an excuse arises).

  3. AlexYak says:

    Hi Kevin,

    I would change it like this:

    return parent.Controls.Cast<Control>().SingleOrDefault(c => c.Name == name);

    -Alex

  4. Kevin Daly says:

    (Still slapping myself on the side of the head for missing that one, hoping brain starts working again).

    This is a bit off-topic, but do you know if Windows Mobile development has survived the cuts?

    More specifically, is Silverlight 2 for Mobile still on track? (I finally got around to watching Amit and Giorgio’s video from the PDC, I’m really pleased at the number of good decisions that have been made – including the substantial upgrade to .NETCF need to support Silverlight 2 – and it would be a terrible shame to see it all shelved).

    I know it sounds heartless to be asking about products when people are losing their jobs, but believe me I’m sympathetic – I and the 3 other employees of my company were all laid off abruptly at the end of September when the parent company in the Netherlands shut down the local operation, and they didn’t even pay us the final pay and holiday pay we were entitled to. So trust me I feel for everyone at MS who has lost or will lose their job.

    But obviously those of us who work with Microsoft technologies need to know which ones are still viable.

  5. AlexYak says:

    Even though I don’t work in the product group, I am pretty sure that Windows Mobile dev is still alive and kicking 🙂

  6. Continuing on this mental exercise that I started in my last post . In this post I started throwing some

  7. Since posting a few of my last ideas , my brain has been running a few background threads on how else

Comments are closed.

Skip to main content