Reputation: 1357
I need to change ResourceDictionary
in App.xaml
file dynamically. I have tried the following code:
ResourceDictionary newRes = new ResourceDictionary();
newRes.Source = new Uri("/PsyboInventory;component/TitleBarResource.xaml", UriKind.RelativeOrAbsolute);
this.Resources.MergedDictionaries.Clear();
this.Resources.MergedDictionaries.Add(newRes);
There is no error, but the theme not change
Upvotes: 5
Views: 13566
Reputation: 2741
In button click you can write this code
var app = (App)Application.Current;
app.ChangeTheme(new Uri("New Uri here"));
ChangeTheme:
public partial class App : Application
{
public ResourceDictionary ThemeDictionary
{
// You could probably get it via its name with some query logic as well.
get { return Resources.MergedDictionaries[0]; }
}
public void ChangeTheme(Uri uri)
{
ThemeDictionary.MergedDictionaries.Clear();
ThemeDictionary.MergedDictionaries.Add(new ResourceDictionary() { Source = uri });
}
}
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="ThemeDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/ShinyRed.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
Upvotes: 4
Reputation: 1357
I solved above problem by adding following code above InitializeComponent()
method in all Window's constructor.
ResourceDictionary newRes = new ResourceDictionary();
newRes.Source = new Uri("/PsyboInventory;component/TitleBarResource.xaml",UriKind.RelativeOrAbsolute);
this.Resources.MergedDictionaries.Clear();
this.Resources.MergedDictionaries.Add(newRes);
Upvotes: 0
Reputation: 39956
Just change:
newRes.Source = new Uri("/PsyboInventory;component/TitleBarResource.xaml", UriKind.RelativeOrAbsolute);
To:
newRes.Source = new Uri("TitleBarResource.xaml", UriKind.Relative);
If you want to change it from a Button_OnClick
event you should change all StaticResource
used in your application to DynamicResource
for example change this:
<Button Style="{StaticResource buttonStyle}" >Click Me!</Button>
To this:
<Button Style="{DynamicResource buttonStyle}" >Click Me!</Button>
Upvotes: 2
Reputation: 10208
Here is the class I use for handling these situations. You can find a complete demo in my GitHub Demo.
namespace JamSoft.CALDemo.Modules.SkinManager
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using JamSoft.CALDemo.Modules.SkinManager.Core;
using JamSoft.CALDemo.Modules.SkinManager.Core.Exceptions;
/// <summary>
/// The skin manager class
/// </summary>
public class SkinManager : DependencyObject, ISkinManager
{
/// <summary>
/// The current skin property
/// </summary>
public static readonly DependencyProperty CurrentSkinProperty = DependencyProperty.Register(
"CurrentSkin",
typeof(Skin),
typeof(SkinManager),
new UIPropertyMetadata(Skin.Null, OnCurrentSkinChanged, OnCoerceSkinValue));
/// <summary>The default skin name</summary>
private const string DefaultSkinName = "Default";
/// <summary>The _skin finder</summary>
private readonly SkinsFinder _skinFinder = new SkinsFinder();
/// <summary>The _skins</summary>
private List<Skin> _skins = new List<Skin>();
/// <summary>
/// Initializes a new instance of the <see cref="SkinManager"/> class.
/// </summary>
public SkinManager()
{
Initialize();
}
/// <summary>Gets the skins.</summary>
/// <value>The skins.</value>
public ObservableCollection<Skin> Skins
{
get
{
return new ObservableCollection<Skin>(_skins);
}
}
/// <summary>Gets or sets the current skin.</summary>
/// <value>The current skin.</value>
public Skin CurrentSkin
{
get
{
return (Skin)GetValue(CurrentSkinProperty);
}
set
{
SetValue(CurrentSkinProperty, value);
}
}
/// <summary>Loads the specified skin or the default if specified skin isn't found.</summary>
/// <param name="skinName">Name of the skin.</param>
public void LoadSkin(string skinName)
{
var skin = _skins.FirstOrDefault(x => x.Name.Equals(skinName)) ?? _skins.FirstOrDefault(x => x.Name == DefaultSkinName);
CurrentSkin = skin;
}
/// <summary>
/// Called when [coerce skin value].
/// </summary>
/// <param name="d">The <paramref name="d"/>.</param>
/// <param name="baseValue">The base value.</param>
/// <returns>the coerced skin <see langword="object"/></returns>
private static object OnCoerceSkinValue(DependencyObject d, object baseValue)
{
if (baseValue == null)
{
return Skin.Null;
}
return baseValue;
}
/// <summary>
/// Called when [current skin changed].
/// </summary>
/// <param name="d">The <paramref name="d"/>.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void OnCurrentSkinChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
try
{
Skin oldSkin = e.OldValue as Skin;
oldSkin.Unload();
Skin newSkin = e.NewValue as Skin;
newSkin.Load();
}
catch (SkinException ex)
{
Console.WriteLine(ex);
}
}
/// <summary>Initializes <c>this</c> instance.</summary>
private void Initialize()
{
_skinFinder.Initialize();
_skins = _skinFinder.SkinsList;
}
}
}
Upvotes: 0