如何扩展而不是替代WPF样式 [英] How to extend instead of overriding WPF Styles
问题描述
我想在我的应用程序中使用自定义主题,据我所知,我可以通过使用资源字典并在App.xaml中引用它来完成此任务.样式将覆盖默认值,例如:
I want to use custom theme in my application and as far as I know I can accomplish this by using resource dictionary and referencing it in App.xaml. Styles would override the defaults like this:
<Style TargetType="{x:Type Label">
<Setter Property="Foreground" Value="Green" />
</Style>
现在,因为我猜默认的标签样式被相同的值覆盖,但是我所有的标签字体均为绿色.当我想在某个地方重新设置标签样式时,问题就开始了.当我想像这样更改网格中的其他属性时
Now as I guess the default Label style is overriden with same values but all my label fonts are green. The problem starts when I want to style one label somewhere again. When I want to change some other property in my Grid like this
<Grid.Resources>
<Style TargetType="{x:Type Label">
<Setter Property="FontSize" Value="28" />
</Style>
</Grid.Resources>
网格中的所有标签都失去了前景色,并再次具有默认值(我是否不能在上一步中覆盖默认值?).经过一番尝试后,我发现要正确执行此操作,我必须向Style
声明BasedOn={StaticResource {x:Type Label}}"
添加另一个属性,并且它可以工作.这对我来说很奇怪,因为现在我将不得不在整个应用程序中重复相同的BasedOn代码,而这不是样式设计的工作原理-应该自动完成!例如,在HTML + CSS样式中,样式被继承和合并,在WPF中,样式被替换...
All labels inside my grid are losing their foreground color and have default one again (didn't I override defaults in previous step?). After some tries I found out that to do this properly i have to add another property to Style
declaration BasedOn={StaticResource {x:Type Label}}"
and it works. This is kind of weird for me because now I will have to repeat same BasedOn code in whole app and this is not how styling works - this should be done automatically! For example in HTML + CSS styles are inherited and merged and in WPF they are replaced...
请注意,当我不使用任何样式控件时,控件仍然会从某种方式(系统主题?)中获得外观.我该如何告诉他们在其他地方查找默认值,因此在样式上没有任何其他代码的情况下,他们会认为默认情况下应该为绿色?
Notice that when I don't use any styles controls still get their look from somehwere (System Themes?). How can I tell them to look for defaults somewhere else so without any additional code on styles they will think that they should be green by default?
有什么方法可以自动设置BasedOn属性?还是有一个更好的整体方法?
Is there any way I can automate setting BasedOn property? Or maybe there is a better to do this overally?
推荐答案
我遇到了同样的问题.我使用了Zack的答案并对其进行了改进,如下所示,因此,如果您不指定样式,则仍会考虑覆盖的默认值.基本上这就是您要做的,但是在ResourceDictionary中只是一次.
I had the same problem. I used Zack's answer and improved it like following so if you don't specify a style the overridden default is still taken in account. It's basically what you would have done but just once in the ResourceDictionary.
<Window x:Class="TestWpf.RandomStuffWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Random Stuff Window">
<Window.Resources>
<ResourceDictionary>
<!-- Default Label style definition -->
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="Green" />
</Style>
<!-- Extending default style -->
<Style TargetType="{x:Type Label}"
x:Key="LargeGreenForegroundLabel"
BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="FontSize" Value="28" />
</Style>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<Button Click="Button_Click">Click</Button>
<Label Content="GreenForegroundLabel" /> <!-- Uses default style -->
<Label Style="{StaticResource LargeGreenForegroundLabel}"
Content="LargeGreenForegroundLabel" />
</StackPanel>
</Window>
这篇关于如何扩展而不是替代WPF样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!