How to load a DictionaryStyle.xaml file at run time?
Changing a theme or style at run-time is possible by assigning styles using DynamicResource binding and loading a ResourceDictionary (XAML) from a Content file at run-time.
This can be done by loading a DictionaryStyle.xaml at run time.
If you would prefer to just jump right in, download the source code: RuntimeLoadOfResourceDictionaryExample.zip
Step 1 – Create a new WPF Application project in Visual Studio
- In Visual Studio, go to File | New | Project.
- Select WPF Application.
- Provide a name for the project and make sure the path is correct.
- Click OK.
Step 2 – Create a basic WPF User Interface
- Create a basic interface.
Note 1: You can make one yourself, or you can use the basic interface I used. Just copy and paste from below.
Note 2: I have already added a menu for selecting the Blue or Grey for you. - Set the Style to use DynamicResource binding.
-
MainWindow.xaml 123456789101112131415161718192021222324252627282930313233343536373839404142<
Window
x:Class
=
"RuntimeLoadOfResourceDictionaryExample.MainWindow"
Title
=
"MainWindow"
Style
=
"{DynamicResource ResourceKey=MainWindowStyle}"
>
<
Grid
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
Height
=
"30"
/>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
Height
=
"25"
/>
</
Grid.RowDefinitions
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
=
"15"
/>
<
ColumnDefinition
Width
=
"*"
MinWidth
=
"100"
/>
<
ColumnDefinition
Width
=
"*"
MinWidth
=
"200"
/>
<
ColumnDefinition
Width
=
"15"
/>
</
Grid.ColumnDefinitions
>
<
DockPanel
Grid.ColumnSpan
=
"4"
>
<
Menu
DockPanel.Dock
=
"Top"
>
<
MenuItem
Header
=
"_File"
>
<
MenuItem
Header
=
"E_xit"
Click
=
"MenuItem_Exit_Click"
/>
</
MenuItem
>
<
MenuItem
Header
=
"_Styles"
>
<
MenuItem
Name
=
"BlueStyle"
Header
=
"_Blue"
Click
=
"MenuItem_Style_Click"
/>
<
MenuItem
Name
=
"GreyStyle"
Header
=
"_Grey"
Click
=
"MenuItem_Style_Click"
/>
</
MenuItem
>
</
Menu
>
</
DockPanel
>
<
Label
Content
=
"First Name"
Name
=
"label1"
Grid.Row
=
"2"
FlowDirection
=
"RightToLeft"
Grid.Column
=
"1"
/>
<
Label
Content
=
"Age"
Name
=
"label3"
Grid.Row
=
"3"
FlowDirection
=
"RightToLeft"
Grid.Column
=
"1"
/>
<
Label
Content
=
"Last Name"
Name
=
"label2"
Grid.Row
=
"4"
FlowDirection
=
"RightToLeft"
Grid.Column
=
"1"
/>
<
TextBox
Name
=
"textBox1"
Grid.Column
=
"2"
Grid.Row
=
"2"
/>
<
TextBox
Name
=
"textBox2"
Grid.Column
=
"2"
Grid.Row
=
"3"
/>
<
TextBox
Name
=
"textBox3"
Grid.Column
=
"2"
Grid.Row
=
"4"
/>
<
Button
Content
=
"Clear"
Grid.Column
=
"2"
Grid.Row
=
"5"
Height
=
"23"
HorizontalAlignment
=
"Right"
Name
=
"button1"
VerticalAlignment
=
"Top"
Width
=
"75"
/>
</
Grid
>
</
Window
>
- Also populate the MainWindow.xaml.cs file with the code-behind needed for some of the events.
MainWindow.xaml 1234567891011private void MenuItem_Exit_Click(object sender, RoutedEventArgs e)
{
Environment.Exit(0);
}
private void MenuItem_Style_Click(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
string stylefile = Path.Combine(App.Directory, "Styles", mi.Name + ".xaml");
App.Instance.LoadStyleDictionaryFromFile(stylefile);
}
It won’t compile just yet as some of the code doesn’t exist yet.
Step 3 – Add code to read in a ResourceDictionary at runtime
This is going to take place in the App.xaml.cs file. App.xaml.cs is the ultimate parent and by loading the ResourceDictionary here, every child will have access to them. This especially becomes important with larger projects where WPF UI elements, controls, windows, or others may come from other dlls.
- Open the App.xam.cs file as shown below.
- Add a function to load the ResourceDictionary at runtime.
- Now add some member variables and create a constructor that loads a style by default.Your class should now look as follows:
App.xaml.cs 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950using
System;
using
System.IO;
using
System.Windows;
using
System.Windows.Markup;
namespace
RuntimeLoadOfResourceDictionaryExample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public
partial
class
App : Application
{
public
static
App Instance;
public
static
String Directory;
private
String _DefaultStyle =
"BlueStyle.xaml"
;
public
App()
{
Instance =
this
;
Directory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string
stringsFile = Path.Combine(Directory,
"Styles"
, _DefaultStyle);
LoadStyleDictionaryFromFile(stringsFile);
}
/// <summary>
/// This funtion loads a ResourceDictionary from a file at runtime
/// </summary>
public
void
LoadStyleDictionaryFromFile(
string
inFileName)
{
if
(File.Exists(inFileName))
{
try
{
using
(
var
fs =
new
FileStream(inFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
// Read in ResourceDictionary File
var
dic = (ResourceDictionary)XamlReader.Load(fs);
// Clear any previous dictionaries loaded
Resources.MergedDictionaries.Clear();
// Add in newly loaded Resource Dictionary
Resources.MergedDictionaries.Add(dic);
}
}
catch
{
}
}
}
}
}
Now, we haven’t create the default style yet, don’t fret, that is the next step.
Step 4 – Create Some Styles
- In Visual Studio, add a new folder to your project called Styles.
- Right-click on the folder and choose Properties.
- Set the Namespace Provider value to false.
- Right-click on the Styles folder and choose Add | Resource Dictionary.
- Provide a file name and make sure that Resource Dictionary (WPF) is selected.
Note: I named my first resource dictionary BlueStyle.xaml. - Click Add.
- Right-click on the BlueStyle.xaml file and choose Properties.
- Set ‘Build Action’ to ‘Content’.
- Set ‘Copy to Output Directory’ to be ‘Copy if newer’.
- Set ‘Custom Tool’ to blank.
- Populate the BlueStyle.xaml with your desired style. Here is the simple style I used for this example.
BlueStyle.xaml 12345678910111213<
Style
x:Key
=
"MainWindowStyle"
TargetType
=
"Window"
>
<
Setter
Property
=
"SizeToContent"
Value
=
"WidthAndHeight"
/>
<
Setter
Property
=
"Background"
Value
=
"RoyalBlue"
/>
</
Style
>
<
Style
TargetType
=
"Label"
>
<
Setter
Property
=
"Margin"
Value
=
"0,5,0,5"
/>
</
Style
>
<
Style
TargetType
=
"TextBox"
>
<
Setter
Property
=
"Margin"
Value
=
"0,5,0,5"
/>
</
Style
>
</
ResourceDictionary
>
- Create a copy of the style named GreyStyle.xaml.
- Repeat steps 7 thru 10 for this new file.
- In the GreyStyle.xaml, change the Background of the MainWindowStyle to DarkGrey.
Step 5 – Build and test
Your project should now be working. You should be able to build and run it. You should be able to click on Styles and change the style.
Hi,
Its not working . Its giving me following error “Failed to create a ‘Type’ from the text ‘Controls:AnimatedContentControl'” . As my file is in Program Data folder in C# i.e. c:\Program Data\abc\dfg\xyz.xaml
When I am trying to load the file its giving me following error.
Regards
Great example to learn from. How to do this in win RT?
thanks a lot.