Welcome to MSDN Blogs Sign in | Join | Help

Alex Yakhnin's Blog

Development and architecture for Windows Mobile devices. And a few useful tips on the way...

News

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 :)

Posted: Saturday, January 10, 2009 4:57 PM by priozersk
Filed under:

Comments

Regev said:

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.

# January 11, 2009 2:42 AM

Kevin Daly said:

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

# January 18, 2009 5:50 PM

priozersk said:

Hi Kevin,

I would change it like this:

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

-Alex

# January 21, 2009 12:31 PM

Kevin Daly said:

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

# January 23, 2009 4:55 PM

priozersk said:

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

# January 24, 2009 10:51 PM

Alex Yakhnin's Blog said:

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

# January 26, 2009 5:06 PM

Alex Yakhnin's Blog said:

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

# February 16, 2009 4:47 PM
Anonymous comments are disabled
Page view tracker