Geeks With Blogs

News
Michael Crump Microsoft MVP, INETA Community Champion and XAML Advocate.

I’ve seen a lot of post describing how to customize a Silverlight Listbox during design time, but sometimes we want the user to have the ability to switch “themes” while the application is running. I originally started working on this for a project that would switch themes during different times of the day and decided to share here.

Go ahead and fire up Blend 4 and select Silverlight Application + Website. Give it a name and hit OK.

image 

We are going to create sample data first. This will give us a Listbox and some great sample data to play with. On the right hand screen hit the Data button and select the button circled below.

image

You will have three choices:

New Sample Data
Import Sample Data from XML
Import Data from Class

Lets select “New Sample Data”. Once you select New Sample Data, you will get the following screen:

image

Go ahead and leave the defaults and hit OK. We now have a SampleDataSource that we can edit any way that we see fit. We are going to keep this simple by clicking the button circled below. This will allow us to change the type from a string to an Image.

image

Change this from:

image to image

We are going to do the same thing for Property2 except change it from a Boolean to a string

image to image

Lets go ahead and add a third Property for a website URL. Click the button highlighted in Red below.

image

 

 

 

 

Now you should have a Property3.

Change Property3 from

image to image

At this point, all of our sample data is created. We are going to simply drag-and-drop the collection to our Artboard to create a Listbox and bind to our data (which is stored as XML – but you don’t need to know that)

image

Go ahead and expand the Listbox to make everything fit better. Hit F5 to take a look at this in your browser. Looks pretty boring right? Let’s see what we can do to make it better.

image

Now look at your Objects and Timelines and right click on your Listbox

image

Take Edit Additional Template –> Edit Generated Items (Item Template) –> Edit a copy

image

 

First off, lets change the StackPanel into a Grid. So Right Click StackPanel and select Change Layout Type and select Grid.

image

You should now have a Grid.

image

 

You should notice that your Artboard looks like this below.

image

We want it to *roughly* look like this one:

image

Remember how we switched from a StackPanel to Grid? That was because the Grid provides the most flexibility to display our data. Now that we have a Grid, we can customize it to give our look and feel that we are aiming for. See the numbers below for instructions

  1. Click here to split the grid into 2 parts.
  2. Click here to provide 2 rows.
  3. Drag the TextBlock [Company Name] into this row.
  4. Drag the TextBlock [Website] into this row.

Hopefully, that wasn’t to painful. If my instructions were not clear then design it however you wish as I’m just teaching the concept. 

image

Now that you have it designed, you can change the font size, colors and even background colors to whatever you want. Below is an example of what I went with. If you notice that I changed the Grid background color to yellow and changed the font of the 2 Textblocks.

image

Once you are done with that, click the ListBox to be brought back to the default User Control.

image

Now look at your Objects and Timelines and right click on your Listbox again. We are going to create our second theme now.

image

Take Edit Additional Template –> Edit Generated Items (Item Template) –> Edit a copy. This time make sure it is named DataTemplate2.

image

 

If you notice it will bring us back to where we were earlier. We are editing the current Item Template. Go ahead and change some of the properties.

You can see an example of what I changed below:

image

 

Again, this was just a simple background and font change. It’s worth noting that as you make changes to the first item that it will effect all the other items in the Listbox.

Now that we have our Templates built, lets go ahead and add 2 buttons and set the Tag.

Michael’s Blend Tip: Hit Ctrl-0 to make the User Control fit the screen.

SNAGHTML53e5fe6

Drag 2 Buttons to the User Control. Setup the following properties for each button.

  1. First button Name : btnTheme1 Second button Name: btnTheme2.
  2. First button Content: Theme 1 Second button Content: Theme 2.
  3. First button Tag: DataTemplate1 Second button Tag: DataTemplate2.

An example of btnTheme1 is below:

image

 

Let’s stop and talk about the Tag. This allows us to store custom information about the object. If you notice that I’m storing which DataTemplate to use in the buttons. This will allow me to setup one method and pass the Tag into it. This is more efficient than creating 2 separate methods.

Now we need to setup an Event Handler for each Button. Follow the example below for both buttons on your form.

  1. Click on the event handler located in red below.
  2. Make sure you are on one of your buttons.
  3. Look for the Click event and type SwitchTemplates

image

To finish up your UI, we will need to give the Listbox a name where we can refer to it in code. Simple click on the Listbox in the Objects and Timelines and name it lstData.

image

At this point, we are finished with XAML and need to add some code behind. Switch to the MainPage.xaml.cs and make sure your SwitchTemplate looks like mine below.

private void SwitchTemplates(object sender, System.Windows.RoutedEventArgs e)
{
    DataTemplate dt;
    dt = (DataTemplate)this.Resources[((Button)sender).Tag.ToString()];
    lstData.ItemTemplate = dt;
}

When the user click on a button it will now switch the template dynamically during runtime! If you want to see my XAML for the Main Page then it is located below:

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
    x:Class="ListboxFun.MainPage"
    Width="640" Height="480">
    <UserControl.Resources>
        <DataTemplate x:Key="DataTemplate1">
            <Grid Height="84" Width="311" RenderTransformOrigin="0.5,0.5" Background="#FFF2FF0D">
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.344*"/>
                    <RowDefinition Height="0.656*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.212*"/>
                    <ColumnDefinition Width="0.788*"/>
                </Grid.ColumnDefinitions>
                <Image Source="{Binding Property1}" HorizontalAlignment="Left" Width="64" Grid.RowSpan="2"/>
                <TextBlock Text="{Binding Property2}" Margin="3,8,-63,0" Grid.Column="1" FontFamily="Andy" FontSize="21.333" FontWeight="Bold"/>
                <TextBlock Text="{Binding Property3}" Grid.Row="1" Grid.Column="1" Margin="3,8,-63,26" FontFamily="Arial Narrow" TextDecorations="Underline"/>
            </Grid>
        </DataTemplate>
        <DataTemplate x:Key="DataTemplate2">
            <Grid Height="83" Width="313" RenderTransformOrigin="0.5,0.5" Background="#FF0D8BFF">
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.344*"/>
                    <RowDefinition Height="0.656*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.236*"/>
                    <ColumnDefinition Width="0.764*"/>
                </Grid.ColumnDefinitions>
                <Image Source="{Binding Property1}" HorizontalAlignment="Left" Width="64" Grid.RowSpan="2"/>
                <TextBlock Text="{Binding Property2}" Margin="3,8,-63,0" Grid.Column="1" FontFamily="Bauhaus 93" FontSize="21.333" FontWeight="Bold"/>
                <TextBlock Text="{Binding Property3}" Grid.Row="1" Grid.Column="1" Margin="3,8,-63,26" FontFamily="Century Gothic" TextDecorations="Underline"/>
            </Grid>
        </DataTemplate>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Source={StaticResource SampleDataSource}}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.338*"/>
            <ColumnDefinition Width="0.662*"/>
        </Grid.ColumnDefinitions>
        <ListBox x:Name="lstData" ItemTemplate="{StaticResource DataTemplate2}" ItemsSource="{Binding Collection}" Margin="0,0,-125,0"/>
        <Button x:Name="btnTheme1" Content="Theme 1" Grid.Column="1" Height="41" Margin="170,32,128,0" VerticalAlignment="Top" Tag="DataTemplate1" Click="SwitchTemplates"/>
        <Button x:Name="btnTheme2" Content="Theme 2" Grid.Column="1" Height="42" Margin="170,77,128,0" VerticalAlignment="Top" Tag="DataTemplate2" Click="SwitchTemplates"/>
    </Grid>
</UserControl>

 

You can actually do a lot of different things with this technique. You could tie this into a users account and upon login give them the view they wish. You could also tie this into different times of the day to provide a brighter theme during day time and a darker theme at night. The possibilities are endless. Feel free to contact me or send me a message on Twitter if you need any help.

Posted on Wednesday, September 22, 2010 4:43 PM Silverlight | Back to top

Copyright © mbcrump | Powered by: GeeksWithBlogs.net