How to load Skins dynamically in WPF

This sample demonstrates how to load skin files dynamically in WPF. A skin file has the file name extension .skin and contains property settings for individual controls such as Button, Label, Textbox, or Calendar controls. Control skin settings are like the control markup itself, but contain only the properties you want to set as part of the theme. For example, the following is a control skin for a Button control.

Getting Started

Creating a WPF Application:

  • Open Visual Studio 2010.
  • Go to File => New => Project
  • Select Windows from the Installed templates and choose WPF application
  • Enter the Name and choose the location.

Click OK.

In my project I have added a folder Skins and I have added three Resource Dictionary using right click of folder and click add new item like this and put the names of resource dictionary files like this:

img1.jpg
Image 1.

I have added three resource dictionary file Red, Blue, Green and add your styles inside of these files. Now let's come on .xaml page work. I am making a Signup windows and loading skins colors dynamically on page.

Here is my windows.xaml

<Window
       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="WpfSkinSample.MainWindow"
       x:Name="Window"
       Title="MainWindow"
       Width="640" Height="480">
    <Window.Resources>
       <DataTemplate x:Key="GroupBoxHeaderStyle">
                     <TextBlock FontWeight="Bold"
                                     Text="{Binding}" />
              </DataTemplate>

              <Style TargetType="Label"
                        x:Key="LabelStyle">
                     <Setter Property="DockPanel.Dock"
                                  Value="Left" />
                     <Setter Property="Width"
                                  Value="100" />
              </Style>

              <Style TargetType="Button"
                        x:Key="ButtonStyle">
                     <Setter Property="HorizontalAlignment"
                                  Value="Right" />
              </Style>            
</Window.Resources>
       <Grid x:Name="LayoutRoot" Margin="5">          
                           
<Grid.RowDefinitions>
                                  <RowDefinition Height="165"></RowDefinition>
                                  <RowDefinition></RowDefinition>
                           </Grid.RowDefinitions>
                           <GroupBox Header="Choose a Skin"
                          HeaderTemplate="{StaticResource GroupBoxHeaderStyle}" Padding="8"
                             Margin="143,-7.5,216,57.5"
                             Background="#FF6FC1CC">
                     <UniformGrid Columns="1" 
                                          x:Name="_skinChanger" FlowDirection="RightToLeft">
                           <RadioButton x:Name="BlueSkin"
                                   Content="Blue Skin" HorizontalAlignment="Left" Width="131" />
                           <RadioButton x:Name="None"
                                  Content="No Skin"
                                  IsChecked="True" HorizontalAlignment="Left" Width="87" />
                           <RadioButton x:Name="RedSkin"
                                  Content="Red Skin" Margin="0,0,0,4" HorizontalAlignment="Left" Width="109" />
                           <RadioButton x:Name="GreenSkin"
                                  Content="Green Skin" HorizontalAlignment="Left" Width="109" />
                     </UniformGrid>
                     <GroupBox.Effect>
                           <DropShadowEffect Opacity="0.25" />
                     </GroupBox.Effect>
              </GroupBox>
              <Grid x:Name="_registerForm" Grid.Row="1">
            <Border Width="400" Height="300"  Style="{DynamicResource BorderStyle}" Margin="75,-48,139,15">
                           <Grid>
                                  <Grid.RowDefinitions>
                                         <RowDefinition Height="0.125*" />
                                         <RowDefinition Height="0.125*" />
                                         <RowDefinition Height="0.125*" />
                                         <RowDefinition Height="0.138*" />
                                         <RowDefinition Height="0.487*" />
                                  </Grid.RowDefinitions>
                                  <DockPanel Grid.Row="0" Margin="0,0,0,8">
                        <Label Content="UserId"  Style="{DynamicResource LabelStyle}" />
                        <TextBox  Style="{DynamicResource TextBoxStyle}"/>
                                  </DockPanel>
                                  <DockPanel Grid.Row="1"  Margin="0,0,0,8">
                        <Label Content="Password"  Style="{DynamicResource LabelStyle}"/>
                        <PasswordBox Style="{DynamicResource PasswordBoxStyle}"></PasswordBox>
                                  </DockPanel>
                                  <DockPanel Grid.Row="2" Margin="0,0,0,8">
                        <Label Content="Email"   Style="{DynamicResource LabelStyle}"/>
                        <TextBox Style="{DynamicResource TextBoxStyle}"  />
                                  </DockPanel>                            
                                  <DockPanel Grid.Row="3" Height="35" VerticalAlignment="Top">
                        <Label Content="First Name"  Style="{DynamicResource LabelStyle}"/>
                        <TextBox Height="29" VerticalAlignment="Top" Style="{DynamicResource TextBoxStyle}" />
                                  </DockPanel>
                                  <DockPanel Grid.Row="4" Height="35.1" VerticalAlignment="Top">
                        <Label Content="Last Name" VerticalAlignment="Top"  Style="{DynamicResource LabelStyle
}"
                                                    />
                        <TextBox Height="34.96" VerticalAlignment="Top"  Style="{DynamicResource TextBoxStyle}"  />
                                  </DockPanel>
                                  <Button Content
="Submit"
                                                Grid.Row="4"
                                                Width="100" Margin="99,48,0,67" Style="{DynamicResource ButtonStyle}" HorizontalAlignment="Left"d:LayoutOverrides
="Width"
                                                 />
                           </Grid>
                     </Border>
              </Grid>
       </Grid>
</Window
>
 

Windows.xaml.cs

public MainWindow()
              {
                     this.InitializeComponent();
            Loaded += RuntimeSkinning_Loaded;

                     // Insert code required on object creation below this point.
              }

        void RuntimeSkinning_Loaded(object sender, RoutedEventArgs e)
        {
            _skinChanger.AddHandler(RadioButton.CheckedEvent, new RoutedEventHandler(OnSkinChanged));
        }

        private void OnSkinChanged(object sender, RoutedEventArgs e)
        {
            string name = (e.OriginalSource as RadioButton).Name;
            _registerForm.Resources.Clear();
            _registerForm.Resources.MergedDictionaries.Clear();

            if (name == "None"return;

            ResourceDictionary skin =
                Application.LoadComponent(new Uri("/WpfSkinSample;component/Skins/" + name + ".xaml"UriKind.Relative)) as ResourceDictionary;
            _registerForm.Resources.MergedDictionaries.Add(skin);

            e.Handled = true;
        }

Now time to run the application.

img2.jpg

Image 2.

When you click on Blue Skin:

img3.jpg

Image 3.

When you click on red Skin.

img4.jpg

Image 4.

When you click on Green Skin.

img5.jpg

Image 5.

This is it. We are done here with implementation of skins in WPF. Question or comments are most welcome on c-sharpcorner comments section.