My WPF project references another project. In the referenced project, I have some colors and brushes defined in it.
Shared dll's resources:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<Color x:Key="FooColor">#FF00FF00</Color>
<SolidColorBrush x:Key="FooColorBrush" Color="{DynamicResource FooColor}" />
</ResourceDictionary>
Main project's App.xaml:
<Application x:Class="MyProject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Shared;component/UI/Resources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
How can I modify the colors/brushes of the shared dll's resources at runtime?
In my App.xaml.cs, I tried:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
//base.OnStartup(e)
// Didn't work - tried modifying the color from this.Resources
this.Resources.Remove("FooColor");
this.Resources.Add("FooColor", Color.FromArgb(255, 255, 255, 0));
// Didn't work - tried modifying the color from the Merged Dictionary
ResourceDictionary sharedResources = this.Resources.MergedDictionaries.First(x => x.Source.OriginalString.Contains("/Shared;component/UI/Resources.xaml"));
sharedResources.Remove("FooColor");
sharedResources.Add("FooColor", Color.FromArgb(255, 255, 255, 0));
}
}
If the resource that I'm trying to modify is defined in the current project's App.xaml, then this works just fine:
this.Resources.Remove(resourceKey);
this.Resources.Add(resourceKey, newValue);
To test it, in my MainWindow.xaml I have:
<Window x:Class="MyProject.MainWindow"
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"
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Shared;component/UI/Resources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<TextBlock Foreground="{DynamicResource FooColorBrush}" Text="Hello world" />
</Window>
Expectation is that the foreground color would be changed to the value I set at runtime in my App.xaml.cs (Color.FromArgb(255, 255, 255, 0)) rather than the color that's defined in the shared resources xaml file (<Color x:Key="FooColor">#FF00FF00</Color>)
Figured it out. All I had to do was remove the MergedDictionaries from my MainWindow.xaml. My App.xaml.cs code was modifying the MergedDictionary of App.xaml, but since I also defined the MergedDictionary on my MainWindow.xaml, MainWindow.xaml was getting another copy of the resources which wasn't being overridden, and took precedence over the edited one from App.xaml.
Changed this:
To this:
Alternatively, I could have added my logic for changing the resources to my MainWindow.xaml.cs: