Page view counter

Creating Controls in Code

In my new video I demonstrate how you can create controls dynamically at run time. The technique is very straight forward, everything you can create declaratively in XAML you can also create dynamically in C#.

xaml

<Button x:Name="Button1" Width="50" Height="30" Content="Click Me" Grid.Row="3" Grid.Column="0" />

C#

Button button2 = new Button();
button2.Width = 75;
button2.Height = 30;
button2.Content = "No, click me!";
button2.SetValue(Grid.RowProperty, 0);
button2.SetValue(Grid.ColumnProperty, 1);
LayoutRoot.Children.Add(button2);

TwoButtons

 

Why Not Dynamically Instantiate All of 'Em?

The case for why you must dynamically instantiate some objects is clear: there are times you just can't know at design time what kind of object you'll need: you must respond to the user's choices and actions. That of course raises the question of why not eschew the XAML altogether and dynamically instantiate all your objects.

There are two answers to this. The first is that it is faster and easier to declare the button in XAML. The second, more important answer is that the XAML is "toolable" -- that is, the XAML can be read and understood by, for example, Expression Blend, while the C# cannot; which makes developing large applications far easier and far more scalable.

If I open the project that created these two buttons in Blend, this is what I see:

DynamicInBlend

 

Blend can read the grid, and the button declared in XAML but is totally unaware of the button created in code.

Conclusion?

The short conclusion is to create objects declaratively at design time when possible, and dynamically at runtime when necessary.  In the abstract this can seem confusing, but when writing code, it is never ambiguous.

Published Monday, May 05, 2008 3:53 PM by jesseliberty

Comments

# re: Creating Controls in Code

Jesse, I really liked thus video, especially towards the end when you got into those tricky challenges. That were good things to learn from.

I do have one technical question that is not 100% directly related to dynamic controls but related to dynamic User Controls. And I was wondering if I should take the time and write the question and if you would either give me a detail answer or perhaps write a blog about it, since many people will need the answer.

Thanks!

..Ben

Monday, May 05, 2008 4:57 PM by BenHayat

# re: Creating Controls in Code

Ben, by all means, ask your question and I'll try to answer if I can.

Monday, May 05, 2008 5:31 PM by jesseliberty

# re: Creating Controls in Code

>>Ben, by all means, ask your question and I'll try to answer if I can.<<

Thank you Sir;

Here is the situation.I'm creating an application that has many User Controls. Some of these UC are more like a full page (container to other controls or UC) and some are independent UC. So for the sake of this discussion, let's call the Container UC as Container.

One way to use these container, is using Xaml and creating these containers at design time and setting their Visibility to Collapse and then at run time, turning the visibility back on again. I don't care for this method so much for Container situation. Number one, all these containers are always created when the application is loaded (and whether the user ever uses them or not) and secondly it clusters my main page by having all these UC but collapsed.

A better way is to dynamically create them as the user (let's say clicks a button), the main form instantiates that container, and when he/she close the container, it's reference is set to null and is gone.

And here is where I'm having a bit of problem (my lack of knowledge of creating delegate and even handler).

Suppose, there is a button on the main form and when the user clicks on the button, a new container gets instantiated and the new container appears on the top of the main form. However, there is also a "Close" button on that container that when the user clicks on, the container closes. And here is my question. When the user clicks on the the "Close" button, I'll set the visibility of that Container to Collapsed, however I need to raise some kind of event in that Close button that the main form (who originally created the Container), will respond to this event that the container has been closed, therefore I need to remove it from the Children.Remove(Container) and then set the container to null.

I don't know how to raise that event in the "Close" button and how to respond to it in the main form.

A sample or explanation or snippet or pointer to some info is much appreciated!

Thanks!

..Ben

p,s. I tried to learn it from your C# book (4th edition) but didn't get that far!

Monday, May 05, 2008 6:54 PM by BenHayat

# re: Creating Controls in Code

Ben,

I have a number of questions about your design.  First, Let me be sure i have this clear... (1) All of this is in Silverlight (not ASP.NET, etc.)  (2) Your design says that I have a standard user control, which I have, say a grid (call it LayoutRoot,

Now, the heart of the design:

At the top of the grid I have two buttons: Create and Close. Create dynamically instantiates a user control of type Container and Close makes it go away. As far as I read your design, both buttons are outside the container.

So, a few questions: (1) what happens if I click Create twice? Do I get two containers?  Or does Create become disabled when one container is created?

(2) Why not have close be within the container so we know which container is being closed intuitively?

(3) why are you collapsing the container on close and then setting it to null? Either you want to make it invisible or you want to destroy it.

So, what I'd suggest is that you use a stack panel as your main layout control to hold your created containers (or a grid, depending on how much work you want to do).

At the top is a button Create. Clicking that button causes a new container (user control) to be added to the stackpanel's children collection (and thus be placed at the bottom of the panel).  

Each user control has, in addition to whatever else it has, a close button with a click event to which the stack panel subscribes. On click, the stack panel is told the ID of the panel that is closing and the stack panel removes it from its children collection - this both makes the user control invisible and moves everything below it in the stack up into position (if you use a grid, you have either a hole in your grid or you have to move them yourself.

Yes, this would make a good video. I'll add it to the list.

Tuesday, May 06, 2008 8:22 AM by jesseliberty

# Dew Drop - May 6, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop - May 6, 2008 | Alvin Ashcraft's Morning Dew

# re: Creating Controls in Code

>>(1) All of this is in Silverlight (not ASP.NET, etc.) <<

Yes!

------

>>Your design says that I have a standard user control, which I have, say a grid (call it LayoutRoot,<<

Yes!

-----

>>At the top of the grid I have two buttons: Create and Close. Create dynamically instantiates a user control of type Container and Close makes it go away. As far as I read your design, both buttons are outside the container.<<

No! The create button is on the main page that creates the User Control (This user control is like a child form) which has it's OWN "Close" button. The "Close" button" is on the the User Control. And for now, by clicking, I set the visibility of the User Control to Collapsed.

-----

>>(1) what happens if I click Create twice?<<

When I show the User Control, It also has a Rectangle underneath that stretches the entire screen, which prevents the user to access the main form to click again. It's like a modal window!

-----

>>(2) Why not have close be within the container so we know which container is being closed intuitively?<<

As mentioned, the Close IS on the container!

-----

>>(3) why are you collapsing the container on close and then setting it to null? Either you want to make it invisible or you want to destroy it.<<

For now, I'm setting it to Collapsed to make it invisible, because I had created the UC at design time. However, once I change my design to create it dynamically, I'd then raise an even in the Close button and the parent would remove it from children and set it to null and I don't need to set it to collapse anymore.

-----

>>Each user control has, in addition to whatever else it has, a close button with a click event to which the stack panel subscribes. On click, the stack panel is told the ID of the panel that is closing and the stack panel removes it from its children collection - this both makes the user control invisible and moves everything below it in the stack up into position (if you use a grid, you have either a hole in your grid or you have to move them yourself.<<

I have already planned the formation of my UC. That's not an issue.

-----

My only point and question is, when an action (i.e. a button on UC is pressed), I need that action to be broadcast, so in the parent an event handler would respond (as you said remove from children and set the reference to null). That's where I need the help!

Thanks!

Tuesday, May 06, 2008 9:30 AM by BenHayat

# W&ouml;chentliche Rundablage: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery&#8230; | Code-Inside Blog

Pingback from  W&ouml;chentliche Rundablage: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery&#8230; | Code-Inside Blog

# Weekly Links: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery&#8230; | Code-Inside Blog International

Pingback from  Weekly Links: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery&#8230; | Code-Inside Blog International

# re: Creating Controls in Code

Jessy,

Thank you for your post, very helpful.

I have a question that is not directly related with this article but probably interesting for the community since is related with handling events

I want to have an event to last while the left mouse is down (like having an object "rotate" while the left mouse is down and then stop rotating when the left mouse is up).

How can I accomplish the "while mouse is down" event functionality ? I notice that the event triggers properly but the code runs only once. When I coded with SL1.1 I used to handle it within Javascript with the setTimeout method.

Thank you for your time and all your help

Wednesday, May 14, 2008 12:37 PM by raspa2k

# re: Creating Controls in Code

>>I want to have an event to last while the left mouse is down (like having an object "rotate" while the left mouse is down and then stop rotating when the left mouse is up). <<

I think I would start the rotate on the MouseDown event and stop the rotate on the MouseUp event.

// pseudocode

myObject_OnMouseUp(object o, MouseEventArgs e)

{

 rotating=false;

}

-j

Wednesday, May 14, 2008 10:27 PM by jesseliberty

# re: Creating Controls in Code

How do you set the x:Name property programatically with dynamic controls?  Silverlight doesn't seem to want to let you for some reason...

Tuesday, May 20, 2008 8:09 AM by SteveFrench

# re: Creating Controls in Code | My Geek Solutions | My Geek &#8230; | My Geek Solutions

Pingback from  re: Creating Controls in Code | My Geek Solutions | My Geek &#8230; | My Geek Solutions

# re: Creating Controls in Code | My Geek Solutions | My Geek ??? | My &#8230; | My Geek Solutions

Pingback from  re: Creating Controls in Code | My Geek Solutions | My Geek ??? | My &#8230; | My Geek Solutions

# re: Creating Controls in Code

How can we find the control which was created dynamically?

Tuesday, June 16, 2009 2:08 AM by rajkra