Loader Custom Control: Dynamically Loading User Controls in Silverlight 2 | John Papa

John Papa

Evangelist on the loose

Loader Custom Control: Dynamically Loading User Controls in Silverlight 2

...

I create a lot of demo applications, and with Silverlight 2 that means creating a lot of user controls.  Sometimes I build entire applications and other times I build simple and focused user controls. Sometimes I have a dozen user controls that I use to demonstrate different topics at events. I created a simple custom user control that loads another user control on demand. This has been very helpful for presentations and for using samples for my Silverlight 2 book.

The custom control I created is called MenuView. It shows a ListBox on the left that displays the information about each user control that I want to load. When the user selects the ListBox item, the user control is loaded dynamically on the right.

image

 

Its pretty straightforward in appearance and can certainly be spruced up. The purpose is to allow me an easy way to dynamically load control I want to demonstrate. The basic structure of the MenuView control is a Grid (shown below). The left hand side holds the ListBox and the right hand side contains a StackPanel, which is where the user controls will be loaded dynamically.

<Grid x:Name="LayoutRoot" Background="#FF2D2D2D">
<Grid.RowDefinitions>
<RowDefinition Height="46"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="215"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Samples" Margin="10,10,10,10" 
Foreground="#FFFFFFFF" Grid.Row="0" Grid.Column="0" 
HorizontalAlignment="Center"/>
<ListBox Margin="10,10,10,20" x:Name="lstMenu" 
ItemTemplate="{StaticResource MenuItemDataTemplate}" 
ItemsSource="{Binding Mode=OneWay}" Grid.Row="1" 
Grid.Column="0" Style="{StaticResource ListBoxStyle}" />
<StackPanel HorizontalAlignment="Stretch" Margin="10,10,10,10" 
VerticalAlignment="Stretch" Grid.Column="1" 
x:Name="ContentPanel" Grid.RowSpan="2"/>
</Grid>

 

The MenuView loads controls when the ListBox selection changes. It creates an instance of the user  control using its type, and its the control to the StackPanel (shown below).

private void lstMenu_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedMenuItem = lstMenu.SelectedItem as MenuItem;
UIElement newUIElement = Activator.CreateInstance(selectedMenuItem.ControlType) as UIElement;
ShowControl(newUIElement);
}
 
private void ShowControl(UIElement newUIElement)
{
while (ContentPanel.Children.Count > 0)
ContentPanel.Children.RemoveAt(0);
ContentPanel.Children.Add(newUIElement);
}

All of this in encapsulate din a Silverlight class library. This allows me to refer to this control in several applications simply by referencing the DLL. So in a Silverlight 2 application where I have several unrelated user controls that I want to use in a presentation, I create a list of MenuItem classes and pass them to the MenuView control. The MenuItem class is a simple class with Title, Description and ControlType properties. Title and Description are displayed in the ListBox menu. The ControlType is used to dynamically load the user control when the selection is made.

private void Application_Startup(object sender, StartupEventArgs e)
{
ObservableCollection<MenuItem> menu = new ObservableCollection<MenuItem>
{
new MenuItem {
Title = "Simple Binding", ControlType = typeof(BindingSimple),
Description = "Shows basic binding to the DataContext"
},
new MenuItem {
Title = "Blend Binding", ControlType = typeof(BlendBinding),
Description = "Shows basic binding to the DataContext created through Expression Blend"
},
new MenuItem {
Title = "Manual Push/Pull", ControlType = typeof(BoundManually),
Description = "Shows pushing and pulling data without using binding"
},
new MenuItem {
Title = "DataContext Binding", ControlType = typeof(DataContextBinding),
Description = "Shows binding using the DataContext at different UIElement levels"
},
new MenuItem {
Title = "RunTime Binding", ControlType = typeof(RuntimeBinding),
Description = "Shows how to bind in .NET code"
}
};
this.RootVisual = new MenuView(menu);
}

If interested, the source code for this control can be downloaded here.

DotNetKicks Image
tags: Silverlight
  • http://www.alvinashcraft.com/2008/09/23/dew-drop-september-23-2008/ Anonymous

    Pingback from Dew Drop – September 23, 2008 | Alvin Ashcraft’s Morning Dew

  • http://www.silverlightshow.net/news/Silverlight-news-for-September-24-2008.aspx Anonymous

    Pingback from Silverlight news for September 24, 2008

  • Anonymous

    I was not able to open the source code.
    Thanks,
    Rachida

  • http://johnpapa.net JohnPapa

    Rachida,
    What is happening when you try to open the project?
    It is zipped with WinRAR. Once extracted you need Silverlight 2 Beta 2 and the tools for Visual Studio to open it.
    – JP

  • http://Thanks Anonymous

    Thanks for the tip, I tried to unzip it using the wrong tool.
    Now it’s unzipped. I have every thing to run silverlight projects. Thanks also for your articles. We need more of this kind of topics. Like switching between pages, navigation, and user controls.
    Thanks,
    Rachida Dukes

  • http://blogger.forgottenskies.com Anonymous

    Thank you – I was just looking for something like this!

  • http://blogger.forgottenskies.com Anonymous

    Sorry to bother, any chance you can provide a sample showing this working?
    I’m new to Silverlight :)

  • Anonymous

    Do you have any sample wpf application I can download?

  • Simon Smith

    How does the control get unload? Does this line fire the unload event ContentPanel.Children.RemoveAt(0);
    Thanks

%d bloggers like this: