WPF动态更改资源文件和主题 [英] WPF Dynamically change resource file and theme

查看:2525
本文介绍了WPF动态更改资源文件和主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目使用ProjectTheme.xaml文件为所有WPF窗口通过项目。
ProjectTheme.xaml文件引用如下样式主题

My project uses a ProjectTheme.xaml file for all WPF windows through out the project. The ProjectTheme.xaml file references a style theme as follows

<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

All WPF Windows references WindowBase.xaml

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/MyProject;component/View/WindowBase.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

WindowBase.xaml引用自定义标题栏Bar1.xaml

WindowBase.xaml references customized titlebar Bar1.xaml

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Bar1.xaml" />
</ResourceDictionary.MergedDictionaries>

Bar1.xaml引用ProjectTheme.xaml

Bar1.xaml references ProjectTheme.xaml

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/MyProject;component/ProjectTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>

所以父母是


  • Window1引用WindowBase.xaml

  • WindowBase引用Bar1.xaml

  • Bar1引用ProjectTheme.xaml

  • ProjectTheme.xaml引用真实的主题资源文件。

  • Window1 references WindowBase.xaml
  • WindowBase references Bar1.xaml
  • Bar1 references ProjectTheme.xaml
  • ProjectTheme.xaml reference the real theme resource file.


现在我想在运行时动态更改项目主题而不退出应用程序。
假设我有几个主题样式文件

This works fine. Now I want to dynamically change the project theme at run time without quitting the app. Assuming that I have several theme style files


  • Customized.xaml

  • xaml

  • Customized2.xaml

我的问题是
在运行时更新ProjectTheme.xaml文件以更改

My question is if it possible to dynamically update ProjectTheme.xaml file at run time to change the line from

<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized.xaml" />

<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized1.xaml" />

以实现我的目标?
如果是,我该怎么办?
如果没有,什么是什么原因和什么是最好的(其他)方式来实现我的目的?

to achieve my objective? If yes, how do I do it? If no, what is the reason and what is the best (other) way to achieve my purpose?

我试过下面但是没有一个工作:样式不变。

I have tried the following but none of them work: the style does not change.

方式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 ...)使用动态资源和静态资源的组合。这是真的吗?

Note: In my real theme style files (Customized.xaml...) I used a combination of dynamic resource and static resource. Does that matters?

提前感谢。

推荐答案

这里有几件事要考虑。

首先,用 StaticResource 定义的任何内容都不会在更改时更新。如果你想要一个控件支持在运行时改变主题,你需要使用 DynamicResource ,这样它就知道要查找变化。

First, anything defined with StaticResource will not get updated on a change. If you want a control to support changing the theme at runtime, you need to use DynamicResource so it knows to look for changes.

改变主题的整体方法是正确的。要实现此目的,最简单的方法是使用应用程序范围的资源字典,确保您的 ResourceDictionary 在您的 App.xaml 中定义。对于添加一个新的资源,我使用类似于下面的代码段:

Your overall approach to changing the theme is correct. The easiest way to accomplish this is using Application-scoped resource dictionaries, making sure your ResourceDictionary is defined in your App.xaml. For adding a new resource, I've used snippets similar to the following:

ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative);

Application.Current.Resources.MergedDictionaries.Add(dict);

您可能会混淆自己的部分是在基类中使用资源。当您在类中定义资源时,资源将位于该类型的实例的本地。考虑XAML编译成自己的 InitializeComponent()方法,这意味着你不能改变原来的XAML,并期望变化去所有的实例。同样,更改类实例上的资源不会影响其他实例。

The part you may be confusing yourself over is when using resources within base classes. When you define a resource in a class, the resource will be local to an instance of that type. Think of the XAML compiling into it's own InitializeComponent() method on classes, meaning you can't change the original XAML and expect the changes to go to all instances. On the same note, changing the resources on a class instance doesn't effect other instances.

由于您的问题确实包含两个单独的问题(应用程序主题和更改控制资源) ,我将专注于确保您的应用程序资源正确更新和使用 DynamicResource ,并希望我提供的信息将足以了解为什么某些其他资源可能不更新

Since your question really contains two separate concerns (application theming and changing control resources), I would focus on ensuring your application resources are updating properly and using DynamicResource, and hopefully the information I've provided would be sufficient for understanding why certain other resources may not be updating yet.

这篇关于WPF动态更改资源文件和主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆