Home > Posts > HowTo: Load a XAML ResourceDictionary from a .NET assembly

HowTo: Load a XAML ResourceDictionary from a .NET assembly

Copying here my answer at:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/11a42336-8d87-4656-91a3-275413d3cc19

What seems to work for me is the following (copying from the source code of http://ClipFlair.codeplex.com [check out the FlipPanel project under “Client” subfolder])

note

I’m using Build Action = "Page" and Custom Tool="MSBuild:Compile" at the properties of Themes\DropDownTheme.xml and Themes\RotateHorizontalTheme.xaml, as was for Themes\Generic.xaml. Seems to work OK (probably this is faster at runtime compared to setting Build Action to Resource and telling it to not build it)

according to http://stackoverflow.com/questions/145752/what-are-the-various-build-action-settings-in-vs-net-project-properties-and-wh the Build Action = "Page" compiles the XAML into BAML (this seems to also apply to Silverlight 5)

* FlipPanel project, Themes\Generic.xaml

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel">
 
  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary 
Source="/FlipPanel;component/Themes/RotateHorizontalTheme.xaml" /> </ResourceDictionary.MergedDictionaries>
<Style TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_RotateHorizontalTemplate}"/> </Style> </ResourceDictionary>

* FlipPanel Project, Themes\RotateHorizontalTheme.xaml

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel">
 
  <ControlTemplate x:Key="FlipPanel_RotateHorizontalTemplate" 
TargetType="local:FlipPanel"> <Grid> ... </Grid> </ControlTemplate> <Style x:Key="FlipPanel_RotateHorizontalStyle" TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_RotateHorizontalTemplate}"/> </Style> </ResourceDictionary>

* FlipPanel Project, Themes\DropDownTheme.xaml

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel">
 
  <ControlTemplate x:Key="FlipPanel_DropDownTemplate" 
TargetType="local:FlipPanel"> <Grid> ... </Grid> </ControlTemplate> <Style x:Key="FlipPanel_DropDownStyle" TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_DropDownTemplate}"/> </Style> </ResourceDictionary>

* FlipPanel.Silverlight.Demo project, FlipPanelTest.xaml

<UserControl x:Class="FlipPanelTest.FlipPanelTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:flip="clr-namespace:FlipPanel;assembly=FlipPanel" >
 
  <UserControl.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary 
Source="/FlipPanel;component/Themes/RotateHorizontalTheme.xaml" /> <ResourceDictionary
Source="/FlipPanel;component/Themes/DropDownTheme.xaml" /> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White" Width="400"> <Grid.RowDefinitions> <RowDefinition Height="300"></RowDefinition> <RowDefinition Height="300"></RowDefinition> </Grid.RowDefinitions> <flip:FlipPanel x:Name="panel1" Grid.Row="0" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White"
Template="{StaticResource FlipPanel_DropDownTemplate}" >
<!-- Style="{StaticResource FlipPanel_DropDownStyle}" -->
<flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip1_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel> <flip:FlipPanel x:Name="panel2" Grid.Row="1" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White"
Template="{StaticResource FlipPanel_RotateHorizontalTemplate}" >
<!-- Style="{StaticResource FlipPanel_RotateHorizontalStyle}" -->
<flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip2_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel>
<flip:FlipPanel x:Name="panel3" Grid.Row="2" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White" >
<!-- using default style here -->
<flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip2_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel>



</Grid> </UserControl>

 

Note that I decided to prefix names with "FlipPanel_", not sure if there’s some better way (using XAML namespaces somehow) to avoid any conflicts when merging the dictionaries and resolving the resouces with "{StaticResource …}"

Also note that in each theme file I also provide a Style (that sets the corresponding Template property of the FlipPanel conrol) that one can use instead of using the Template directly. At that Style more FlipPanel control properties could be set to values appropriate for that template (the template defines a skeleton and the style dresses the pirate [skeleton] as somebody cleverly pointed out).

Note that Generic.xaml merges and uses the templat from one of the themes. Couldmake copies of files similar to Generic.xaml and reference the same template but with different values in the Style for other properties to make variations without resorting to Copy/Paste when multiple Themes use the same Template but restyle it a bit.

Another important note is that at Generic.xaml you must not use x:Key="FlipPanel_DefaultStyle" or anyother key at the default style, or the command

        public FlipPanel()
        {
            DefaultStyleKey = typeof(FlipPanel);
        }

won’t load the default style (which is needed when you don’t provide a Template or Style value at the consumer XAML (FlipPanelTest.xaml). Probably one can modify it to load a style by name instead of just by type (probably the issue was that it found multiple named styles applying to that type [both FlipPanel_RotateHorizontalStyle and FlipPanel_DefaultStyle] in the Generic.xaml), but removing the Key and using an unnamed style seems to do the trick.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: