Asked by:
Load a ResourceDictionary from an assembly

Question
-
I have an assembly in which I have some n number of ResourceDoctionary XAML files under Icons folder. How do I get and how to access all the resource dictionary files and how to use it in my applocaiton?
PrabuTuesday, July 21, 2009 5:07 AM
All replies
-
In xaml, like this:
<myObject.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!-- Load theme --> <ResourceDictionary Source="/MyAssembly.UI;component/themes/mytheme.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </myObject.Resources>
Geert van Horrik - CatenaLogic
Visit my blog: http://blog.catenalogic.comTuesday, July 21, 2009 8:18 AM -
There are three steps:
- You need set the Build Action property of the resource/s (in the component) to Resource.
(For Example an image in icons/example.png in Client.Resources.dll ) - In the .exe set a new reference to the component (.dll)
- In the .exe use this sintaxis to access to the resource of the dll:
<ImageBrush ImageSource="pack://application:,,,/Client.Resources;component/icons/example.png" />
Andoni Arroyo M.C.P. (70.300, 70.315, 70.305) Por favor marca como respuesta si te ha ayudado esta respuestaTuesday, July 21, 2009 8:21 AM - You need set the Build Action property of the resource/s (in the component) to Resource.
-
Hi,
I think you were misunderstood. I want to iterate all the ResourceDoctionary files present in the assembly through code behind. The name of the ResourceDoctionary file in assembly is unknown. Each ResourceDictonary file, I have several drawing brushes for Icons. I want to access all those ResourceDoctionary file.
PrabuTuesday, July 21, 2009 8:39 AM -
While I understand this doesnt answer your question fully, it might solve your problem if you know the assembly and xaml resource file name.
Once you figure out the assemblies/xaml files to use, you can add them to the app resource dictionary by:
ResourceDictionary dictionary = new ResourceDictionary(); dictionary.Source = new Uri("/assemblyName;component/xamlfile.xaml", UriKind.RelativeOrAbsolute); Application.Current.Resources.MergedDictionaries.Add(Dictionary);
If the xaml file is in a dir, specifiy it by ";component/dir/xamlfile.xaml" component is a key word here.
Or you can build your uri in whatever fashion works for you using the pack://application:,,, syntax.
That way, the resources should be resolvable by other xaml files at runtime, if they aren't already.Tuesday, July 21, 2009 11:45 AM -
Hi,
Thanks for answering.
But this is not case of mine. In my case, I know only the assembly name. In that assembly there are different categories (ResourceDoctionary files) [For Ex:- Currently I have 5 categories in that assembly. Later we can include more categories [more ResourceDictionary files]]. Each categories will have some n number of icon images in the form of DrawingBrushes. I want to access all the ResourceDictionary files from the assembly. From the Each ResourceDictionary, I can read the icon files.
Thanks for your reply.
PrabuTuesday, July 21, 2009 12:35 PM -
From the assembly, you can get all the resources and check if they are XAML/BAML files and then load them to see if they are ResourceDictionaries. This is going to be prohibitively expensive however.
I highly reccommend that you find a way to find another mechanism to have a list of ResourceDictionaries instead. Could you have one ResourceDictionary that uses MergedDictionaries like the other posters recommended? You could add as many other "catagories" as you want as long as you add a merge dictionary reference to itTuesday, July 21, 2009 5:48 PM -
Hi,
As you recommended, how do I get the ResourceDictionaries present in the assembly? If I get the ResourceDictionary files names then I can easily merge all the ResourceDictionaries and I can get all the resources with help of keys.
PrabuTuesday, July 28, 2009 4:10 AM -
what seems to work for me is the following (copying from the source code of http://ClipFlair.codeplex.com [currently under development])
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> <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/template 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. Could make 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.
- Proposed as answer by George Birbilis Monday, June 11, 2012 3:30 PM
- Edited by George Birbilis Monday, June 11, 2012 4:03 PM fixed to work with default style/template too
- Unproposed as answer by OmegaMan Wednesday, July 11, 2012 2:56 PM
Monday, June 11, 2012 2:43 PM -
I'm surprised this has no answer and every proposed answer is trying to answer a question that the OP clarified he isn't asking. Imagine you want to build a tool that opens a .DLL and provides a browser of all the XAML resources in the DLL that also displays the full pack URI to the resource. Not to use them in a XAML project, but just simply to see what they are. I'm searching for such a tool.Tuesday, October 29, 2019 4:49 PM