I want to achieve themes in my WPF program.
I stored the color in the database and then load it into MergedDictionaries
.
Here are my codes:
<Application x:Class="Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And here are code-behind:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Resources;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Resources;
namespace Test
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
ChangeTheme("Dark");
}
public ResourceDictionary ThemeDictionary
{
get { return Resources.MergedDictionaries[0]; }
}
public void ChangeTheme(string ThemeName)
{
Resources.MergedDictionaries.Clear();
Resources.MergedDictionaries.Add(new ResourceDictionary());
///some logic to load color from database
ThemeDictionary.Add("NormalBackground",new SolidColorBrush(Colors.Red));
}
}
}
And here are sample of front-end:
<Window x:Class="Test"
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"
xmlns:local="clr-namespace:Test"
mc:Ignorable="d"
Height="450" Width="800">
<Grid Background="{StaticResource NormalBackground}">
</Grid>
</Window>
After the program ran. VS reports error that cannot find StaticResource "NormalBackground".
Whereas, if I add an exist ResourceDictionary into the MergedDictionaries, all works well.
What's wrong with my code? Thank you.
You are calling "ChangeTheme("Dark")" too early. It should be called from within OnStartup in App.xaml.cs. I guess that the resource dictionaries defined in the xaml (which is empty in your case) will overwrite everything you put in there by code in your constructor.
public App()
{
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ChangeTheme("Dark");
}
Also, you can remove the inner part of your MergedDictionaries from you App.xaml
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>