WPF 动态更改资源文件和主题

编程入门 行业动态 更新时间:2024-10-26 12:23:17
本文介绍了WPF 动态更改资源文件和主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我的项目在整个项目中为所有 WPF 窗口使用 ProjectTheme.xaml 文件.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="schemas.microsoft/winfx/2006/xaml/presentation" xmlns:x="schemas.microsoft/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 引用了真实的主题资源文件.

这很好用.现在我想在不退出应用程序的情况下在运行时动态更改项目主题.假设我有几个主题样式文件

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
  • Customized1.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.

方式一

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

方式二

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?

提前致谢.

推荐答案

这里有几件事情需要考虑.

There are a few things to consider here.

首先,使用 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 动态更改资源文件和主题

本文发布于:2023-07-17 03:40:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1129044.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:文件   动态   主题   资源   WPF

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!