首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Windows 10 XAML“主题化”样式

Windows 10 XAML“主题化”样式
EN

Stack Overflow用户
提问于 2015-08-12 07:00:32
回答 1查看 1.3K关注 0票数 0

我想让ComboBoxes在我的Windows10应用程序中有主题颜色(一个有绿色的主题,一个有橙色的theme...etc)。我可以为每一种不同的颜色制作不同的样式,但这会增加大量的标记,这是一个混乱的管理。因为它们也是样式,所以我看到绑定不起作用,因为样式一旦初始化就会被密封。

有没有人想出一种方法,只改变一种样式的颜色,而不必制造多个不同的样式?

EN

回答 1

Stack Overflow用户

发布于 2015-08-12 14:12:00

对于这个问题,WPF有一些很好的标记。您可以使用DynamicResource在每次资源更改时允许样式刷新。下面是一个例子:

代码语言:javascript
运行
复制
<SolidColorBrush x:Key="ColourAccent">#448AFF</SolidColorBrush>

<Style TargetType="Button">
    <Setter Property="Background" Value="{DynamicResource ColourAccent}"/>
</Style>

当然,这是该方法的一个非常简单的实现,但本质上,DynamicResource是对ColourAccent的引用,如果要更改资源,它将自动反映样式中的更改。

现在,更改资源是一个稍微不同的问题,对于主题化(您的样式),您需要在某个地方放置所有颜色,这里的解决方案是使用多个ResourceDictionaries和使用MergedDictionaries。让我告诉你我的意思:

首先,向您的项目添加一个名为Themes的文件夹,这样只会使事情变得更简单。另外,将前面提到的Style添加到Window.ResourcesApp.Resources中,这是非常重要的。

您需要向文件夹中添加一个Amber.xaml),文件(称为ResourceDictionary文件),如下所示:

代码语言:javascript
运行
复制
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- Amber -->
    <SolidColorBrush x:Key="ColourAccent">#FFC107</SolidColorBrush>
</ResourceDictionary>

这里有一个简单的资源字典,它包含一个名为ColourAccent的资源,现在我们需要创建另一个资源(称为Blue.xaml),但是颜色不同:

代码语言:javascript
运行
复制
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- Blue -->
    <SolidColorBrush x:Key="ColourAccent">#448AFF</SolidColorBrush>
</ResourceDictionary>

这里的魔法很快就会变得清晰起来。拥有具有相同名称的资源的多个资源字典,将允许您创建主题。其方法是将当前资源字典替换为新的资源字典,这样做,DynamicResource将注意到发生了更改,并刷新控件样式。

现在您有了两个资源字典,您需要计算出使用使用的字典。首先,我们需要定义应用程序将要使用的默认资源字典,您需要在App.xaml中声明这一点。

代码语言:javascript
运行
复制
<Application ...>
    <Application.Resources>
        <ResourceDictionary>
            ...
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/YourNamespace;component/Themes/Amber.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>        
    </Application.Resources>
</Application>

在这里,您将看到MergedDictionaries元素,这就是魔术发生的地方。如果你现在运行这个应用程序,你应该会看到任何按钮都会有琥珀的背景颜色。很酷是吧?

现在,它变得更加棘手,我们将删除当前在字典中的资源字典,并将其替换为不同的主题(不同的资源字典)。

这里有一些C#可以这样做:

免责声明:我只是把这些代码放在一起,几乎可以肯定有一个更好的方法,但是你明白了。将下面的代码放在鼠标单击事件中,或者放在您可以逐步执行以查看正在发生的事情的某个地方。

首先,从合并的字典中删除当前的主题。

代码语言:javascript
运行
复制
//Find the current dictionary
ResourceDictionary oldDictionary = App.Current.Resources.MergedDictionaries.FirstOrDefault();

//If we found one, remove it.
if (dictionary != null)
    App.Current.Resources.MergedDictionaries.Remove(oldDictionary);

现在我们只需要添加一个不同的资源字典。为了举个例子,我将添加Blue主题:

代码语言:javascript
运行
复制
//Declare some variables.
string folderPath = "/YourNamespace;component/Themes/";
string desiredTheme = "Blue";

//Create the new resource dictionary
ResourceDictionary newDictionary = new ResourceDictionary();
newDictionary.Source = new Uri(string.Format("{0}{1}.xaml", folderPath, desiredTheme), UriKind.RelativeOrAbsolute);

//Add the resource dictionary to the merged dictionaries.
App.Current.Resources.MergedDictionaries.Add(newDictionary);

如果一切顺利,应用程序中任何按钮的背景都应该是Blue。万岁!

使用此方法(实质上是创建多个资源字典,每个资源都以相同的名称命名),您可以为应用程序创建多个主题。这不限于颜色,你可以有整个风格,是特定的主题,其中一个主题可能显示一个完全不同的方式作为另一个风格。做个实验,看看你能想出什么。祝好运!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31958128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档