Thursday, February 18, 2010

How to add dynamic silverlight controls in runtime?

In Silverlight, While it is possible to create all your controls and objects in code, best practices dictate that it is usually better to do so in Xaml. The most compelling reason is that Xaml is highly "toolable" - that is, it lends itself to round-trip modification in tools such as Visual Studio and Expression and thus is easier to scale, modify and maintain.

On the other hand, there are times that you can't know at design time which or how many objects you'll need, and the ability to create objects dynamically can be a fundamental requirement.

So let's create a Silverlight page and add the following:

<Canvas x:Name="myCanvas">
<Button x:Name="myButton" Content="Hello" Canvas.Left="10" Canvas.Top="10"/>
<Button x:Name="Another" Content="Add Another" Canvas.Left="10" Canvas.Top="50" />

The objective is to add a button to the page with the words "Add Another." When the user clicks on this button, we want to add a button to the UI and we want that button to have its own size, position and behavior. We do all of that in the code behind.

The first thing to do is to add an event handler for the new button in the Page Load event,

Another.Click += new RoutedEventHandler(Another_Click);

And to add its implementation, in which you'll create a new button and set its properties,

void Another_Click(object sender, RoutedEventArgs e)
Button b = new Button();
b.Content = "I live!";
b.SetValue(Canvas.LeftProperty, 10.0);
b.SetValue( Canvas.TopProperty,
this.newButtonPosition += 30.0;
b.Width = 100;
b.Height = 20;
b.Click +=new RoutedEventHandler(new_button_click);

void new_button_click(object sender, RoutedEventArgs e)
Button btn = sender as Button;
btn.Content = "Don't do that!";
btn.IsEnabled = false;

Because the canvas's Left and Top are not actually properties of the Button (but are extended properties) you set them with the SetValue method, which takes two parameters. The first is the actual name of the property you want to set (Canvas.LeftProperty and Canvas.TopProperty) which is not difficult to find as Intellisense will supply it) and the second is the value (in this case a double).

Also we have added an event handler registration to the button. This means that every button that is added is registered to call new_button_click when it is clicked. As the buttons are clicked, they change their message and become disabled.