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
    #1 Dew Drop - September 23, 2008 | Alvin Ashcraft's Morning Dew on 9.23.2008 at 3:25 PM

    Pingback from Dew Drop - September 23, 2008 | Alvin Ashcraft's Morning Dew



    #2 Silverlight news for September 24, 2008 on 9.24.2008 at 4:07 AM

    Pingback from Silverlight news for September 24, 2008



    #3 Rachida Dukes on 9.25.2008 at 1:04 PM

    I was not able to open the source code.

    Thanks,

    Rachida



    #4 John Papa on 9.25.2008 at 1:10 PM

    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



    #5 Rachida Dukes on 9.25.2008 at 3:23 PM

    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



    #6 Steve on 10.29.2008 at 2:56 PM

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



    #7 Steve on 10.29.2008 at 3:16 PM

    Sorry to bother, any chance you can provide a sample showing this working?

    I'm new to Silverlight :)



    Leave a Comment