I’m trying to create a ResourceDictionary
containing icons that use Brushes
defined in other dictionaries in order to dynamically load light and dark themes.
Icons.xaml
<ResourceDictionary xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="schemas.microsoft.com/winfx/2006/xaml">
<DrawingImage x:Key="IconImage">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="{DynamicResource SquareBrush}" Geometry="M0,0 L100,0 100,100 0,100 Z"/>
<GeometryDrawing Brush="{DynamicResource CircleBrush}" Geometry="M25,25 A25,25 0 1 0 75,25 A25,25 0 1 0 25,25"/>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</ResourceDictionary>
Light.xaml
<ThemeDictionary xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="BackgroundBrush" Color="White" />
<SolidColorBrush x:Key="SquareBrush" Color="Green" />
<SolidColorBrush x:Key="CircleBrush" Color="Red" />
</ThemeDictionary>
Dark.xaml
<ThemeDictionary xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="BackgroundBrush" Color="#1e1e1e" />
<SolidColorBrush x:Key="SquareBrush" Color="Yellow" />
<SolidColorBrush x:Key="CircleBrush" Color="Blue" />
</ThemeDictionary>
App.xaml
<Application x:Class="Test.App"
xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test"
xmlns:icon="clr-namespace:Test.Icons;assembly=Test.Icons"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Test.Icons;component/Icons.xaml" />
<ResourceDictionary Source="pack://application:,,,/Test.Icons;component/Light.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
This is how is used:
<Image Source="{DynamicResource IconImage}" Width="16" Margin="2"/>
This is how I select the theme:
private void LoadResources(bool dark)
{
const string lightName = "Light.xaml";
const string darkName = "Dark.xaml";
string previous = dark ? lightName : darkName;
string current = dark ? darkName : lightName;
List<ResourceDictionary> dicts = Application.Current.Resources.MergedDictionaries.Where(ee => ee?.Source?.OriginalString?.Contains(previous) == true).ToList();
foreach (ResourceDictionary? dict in dicts)
{
Uri source = dict.Source;
Uri curUri = new(source.OriginalString.Replace(previous, current), source.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative);
dict.Source = curUri;
}
}
When I change theme, nothing happens to the IconImage
displayed.
Other resources, such as the BackgroundBrush
, load correctly.
What I doing wrong?
PS: If I remove Icons.xaml
and paste the content to the end of Light
/Dark.xaml
, it work fine, but I thing that in this case, whole IconImage
is loaded.
1