我的项目在整个项目中为所有WPF窗口使用ProjectTheme.xaml文件。 ProjectTheme.xaml文件引用样式主题,如下所示
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<!-- In order to modify the project's theme, change this line -->
<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
所有WPF Windows引用WindowBase.xaml
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProject;component/View/WindowBase.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
WindowBase.xaml引用自定义标题栏Bar1.xaml
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Bar1.xaml" />
</ResourceDictionary.MergedDictionaries>
Bar1.xaml引用了ProjectTheme.xaml
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProject;component/ProjectTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
所以heriarchy是
这很好用。 现在我想在运行时动态更改项目主题而不退出应用程序。 假设我有几个主题样式文件
我的问题是 如果可以在运行时动态更新ProjectTheme.xaml文件来更改该行 从
<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized.xaml" />
到
<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized1.xaml" />
实现我的目标? 如果是,我该怎么办? 如果不是,原因是什么?实现目标的最佳(其他)方式是什么?
我尝试了以下但没有一个工作:风格不会改变。
方式1
Application.Current.Resources.MergedDictionaries.Clear();
Uri NewTheme = new Uri(@"/MyProject;component/Themes/WPFThemes/Customized2.xaml", UriKind.Relative);
ResourceDictionary dictionary = (ResourceDictionary)Application.LoadComponent(NewTheme);
Application.Current.Resources.MergedDictionaries.Add(dictionary);
方式2
Application.Current.Resources.MergedDictionaries.RemoveAt(0);
Uri NewTheme = new Uri(@"/MyProject;component/Themes/WPFThemes/Customized2.xaml", UriKind.Relative);
ResourceDictionary dictionary = (ResourceDictionary)Application.LoadComponent(NewTheme);
Application.Current.Resources.MergedDictionaries.Insert(0, dictionary);
注意: 在我的真实主题样式文件(Customized.xaml ...)中,我使用了动态资源和静态资源的组合。这有关系吗?
提前致谢。
答案 0 :(得分:15)
这里有几点需要考虑。
首先,使用StaticResource
定义的任何内容都不会更新。如果您希望控件支持在运行时更改主题,则需要使用DynamicResource
,以便它知道要查找更改。
您改变主题的整体方法是正确的。最简单的方法是使用Application-scoped resource dictionaries,确保ResourceDictionary
中定义了App.xaml
。为了添加新资源,我使用了类似于以下内容的代码段:
ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(dict);
您可能会混淆的部分是在基类中使用资源时。在类中定义资源时,资源将是该类型实例的本地资源。可以想象XAML在类上编译自己的InitializeComponent()
方法,这意味着您无法更改原始XAML并期望更改转到所有实例。同样,更改类实例上的资源不会影响其他实例。
由于您的问题确实包含两个独立的问题(应用主题和更改控制资源),我将专注于确保您的应用程序资源正确更新并使用DynamicResource
,并希望我提供的信息足够了解为什么某些其他资源可能尚未更新。