I have a .NET8.0 WPF project where I have multiple release build configurations. I want to have different color schemes depending on the config when I building the project.
My resource dictionary StyleDictionary.xaml is looking like this
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- Colors and brushes -->
<Color x:Key="PrimaryBlue1">#009CDD</Color>
<Color x:Key="PrimaryBlue2">#68BDEF</Color>
<Color x:Key="PrimaryBlue3">#9BD3F4</Color>
<Color x:Key="PrimaryBlue4">#CDE9FA</Color>
<SolidColorBrush x:Key="MyProgramAccent"
Color="{StaticResource PrimaryBlue1}" />
<SolidColorBrush x:Key="MyProgramAccentLighter"
Color="{StaticResource PrimaryBlue2}" />
and is included in app.xaml like this
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./Resources/StyleDictionary.xaml" />
</ResourceDictionary>
</Application.Resources>
I want to have a second stylesheet setting my brushes "MyProgramAccet" and "MyProgramAccet" with the color that build. In the .csproj file you can have a "Condition" attribute to many of the items or resources like
Condition="'$(Configuration)'=='Release1'
but I can't find that here.
I thought of having a OnStartup override in app.xaml.cs where I change the file depending on the config but this can not build due to not finding the keys of the solid brushes when compiling
protected override void OnStartup(StartupEventArgs e)
{
Resources.MergedDictionaries.Clear();
var assemblyConfigurationAttribute = typeof(App).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>();
var buildConfigurationName = assemblyConfigurationAttribute?.Configuration;
if (buildConfigurationName == "Release1")
{
Resources.MergedDictionaries.Add(new ResourceDictionary
{
Source = new Uri("pack://application:,,,/Resources/StyleDictionary2.xaml")
});
}
else
{
Resources.MergedDictionaries.Add(new ResourceDictionary
{
Source = new Uri("pack://application:,,,/Resources/StyleDictionary2.xaml")
});
}
MainWindow mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
base.OnStartup(e);
}
How should I think here?
You must reference all dynamic resources using the
DynamicResourcemarkup extension.For example:
This way the XAML parser will not try to evaluate the referenced resource at compiletime. Instead, the reference will be resolved at runtime.
Changing a
ResourceDictionaryat runtime triggers a layout invalidation of the owner which results in all dynamic resources being reapplied: if the references are specified usingDynamicResourcethen the referencing property will reevaluate the reference that now potentially points to a new different resource- like in your case.