如何动态更改ResourceDictionary

我需要动态更改App.xaml文件中的ResourceDictionary 。 我试过以下代码:

 ResourceDictionary newRes = new ResourceDictionary(); newRes.Source = new Uri("/PsyboInventory;component/TitleBarResource.xaml", UriKind.RelativeOrAbsolute); this.Resources.MergedDictionaries.Clear(); this.Resources.MergedDictionaries.Add(newRes); 

没有错误,但主题没有改变

在按钮单击中,您可以编写此代码

var app =(App)Application.Current; app.ChangeTheme(新的Uri(“New Uri here”));

 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 }); } }          

只是改变:

 newRes.Source = new Uri("/PsyboInventory;component/TitleBarResource.xaml", UriKind.RelativeOrAbsolute); 

至:

 newRes.Source = new Uri("TitleBarResource.xaml", UriKind.Relative); 

如果要从Button_OnClick事件更改它,您应该将应用程序中使用的所有StaticResource更改为DynamicResource ,例如更改:

  

对此:

  

这是我用来处理这些情况的类。 您可以在我的GitHub演示中找到完整的演示 。

 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; ///  /// The skin manager class ///  public class SkinManager : DependencyObject, ISkinManager { ///  /// The current skin property ///  public static readonly DependencyProperty CurrentSkinProperty = DependencyProperty.Register( "CurrentSkin", typeof(Skin), typeof(SkinManager), new UIPropertyMetadata(Skin.Null, OnCurrentSkinChanged, OnCoerceSkinValue)); /// The default skin name private const string DefaultSkinName = "Default"; /// The _skin finder private readonly SkinsFinder _skinFinder = new SkinsFinder(); /// The _skins private List _skins = new List(); ///  /// Initializes a new instance of the  class. ///  public SkinManager() { Initialize(); } /// Gets the skins. /// The skins. public ObservableCollection Skins { get { return new ObservableCollection(_skins); } } /// Gets or sets the current skin. /// The current skin. public Skin CurrentSkin { get { return (Skin)GetValue(CurrentSkinProperty); } set { SetValue(CurrentSkinProperty, value); } } /// Loads the specified skin or the default if specified skin isn't found. /// Name of the skin. public void LoadSkin(string skinName) { var skin = _skins.FirstOrDefault(x => x.Name.Equals(skinName)) ?? _skins.FirstOrDefault(x => x.Name == DefaultSkinName); CurrentSkin = skin; } ///  /// Called when [coerce skin value]. ///  /// The . /// The base value. /// the coerced skin  private static object OnCoerceSkinValue(DependencyObject d, object baseValue) { if (baseValue == null) { return Skin.Null; } return baseValue; } ///  /// Called when [current skin changed]. ///  /// The . /// The  instance containing the event data. 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); } } /// Initializes this instance. private void Initialize() { _skinFinder.Initialize(); _skins = _skinFinder.SkinsList; } } } 

我通过在所有Window的构造函数中的InitializeComponent()方法上面添加以下代码来解决上述问题。

 ResourceDictionary newRes = new ResourceDictionary(); newRes.Source = new Uri("/PsyboInventory;component/TitleBarResource.xaml",UriKind.RelativeOrAbsolute); this.Resources.MergedDictionaries.Clear(); this.Resources.MergedDictionaries.Add(newRes);