wpf 蒙皮:使用一种颜色作为另一种颜色的静态资源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4802419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Skinning: Using a Color as StaticResource for another Color
提问by Amenti
I implemented skinning in my application. The application loads its Brushes.xaml resource dictionary which uses colors which reside in a skin-specific resource dictionary. So only one Color.xaml is loaded depending on the chosen skin.
我在我的应用程序中实现了蒙皮。应用程序加载它的 Brushes.xaml 资源字典,该字典使用驻留在特定于皮肤的资源字典中的颜色。因此,根据所选的皮肤,只会加载一个 Color.xaml。
Skin-Specific Color.xaml
皮肤特定颜色.xaml
<Color x:Key="TextBoxBackgroundColor">#C4AF8D</Color>
<Color x:Key="TextBoxForegroundColor">#6B4E2C</Color>
<Color x:Key="ToolBarButtonForegroundColor">#6B4E2C</Color>
Brushes.xaml:
画笔.xaml:
<SolidColorBrush
x:Key="TextBoxBackground"
Color="{DynamicResource TextBoxBackgroundColor}" />
<SolidColorBrush
x:Key="TextBoxForeground"
Color="{DynamicResource TextBoxForegroundColor}" />
As you can see, multiple colors (TextBoxForegroundColor and ToolBarButtonForegroundColor) are the same. I'd like to circumvent that as it is getting more and more confusing especially since the used colors are not recognizable by their hex value. You could advise now to merge both Colors into one but I have skins where the TextBoxForegroundColor is different from the ToolBarButtonForegroundColor.
如您所见,多种颜色(TextBoxForegroundColor 和 ToolBarButtonForegroundColor)是相同的。我想规避它,因为它变得越来越令人困惑,尤其是因为使用的颜色无法通过其十六进制值识别。您现在可以建议将两种颜色合并为一种,但我的皮肤中 TextBoxForegroundColor 与 ToolBarButtonForegroundColor 不同。
What I would like to do is something like this:
我想做的是这样的:
<Color x:Key="DarkBrown">#C4AF8D</Color>
<Color x:Key="TextBoxBackgroundColor" Color={StaticResource DarkBrown} />
<Color x:Key="ToolBarButtonForegroundColor" Color={StaticResource DarkBrown} />
Is this at all possible in Xaml? I didn't find a way.
这在 Xaml 中完全可能吗?我没有找到办法。
采纳答案by H.B.
This?
这个?
<Color x:Key="DarkBrown">#C4AF8D</Color>
<DynamicResource x:Key="TextBoxBackgroundColor" ResourceKey="DarkBrown"/>
<DynamicResource x:Key="ToolBarButtonForegroundColor" ResourceKey="DarkBrown"/>
For more advanced use cases and multiple levels of aliasing see this answer.
有关更高级的用例和多级别名,请参阅此答案。
回答by Pavlo Glazkov
Why don't you just make Brushes.xaml skin-specific? Then you will have this:
为什么不让 Brushes.xaml 特定于皮肤?然后你会有这个:
<Color x:Key="DarkBrown">#C4AF8D</Color>
<SolidColorBrush x:Key="TextBoxBackgroundBrush" Color="{StaticResource DarkBrown}" />
<SolidColorBrush x:Key="ToolBarButtonForegroundBrush" Color="{StaticResource DarkBrown}" />
Another point in favor of making brushes skin-specific is that there are situations where you would want to make the ToolBarButtonForegroundBrush
a solid color brush in one skin and a gradient brush in another skin.
有利于制作特定于皮肤的画笔的另一点是,在某些情况下,您可能希望ToolBarButtonForegroundBrush
在一个皮肤中制作纯色画笔,在另一个皮肤中制作渐变画笔。
回答by cplotts
H.B.'s answer is very interesting and I have played around with it quite a bit since I want to do exactly what this question is asking to do.
HB 的回答非常有趣,我已经玩了很多,因为我想完全按照这个问题的要求去做。
What I've noticed is that using a DynamicResource doesn't work for WPF 3.5. That is, it throws an exception at run time (the one Amenti talks about). However, if you make colors that are referencing the color you want to share ... a StaticResource, it works on both WPF 3.5 and WPF 4.0.
我注意到的是,使用 DynamicResource 不适用于 WPF 3.5。也就是说,它在运行时抛出异常(Amenti 谈到的那个)。但是,如果您制作的颜色引用了您想要共享的颜色......静态资源,它适用于 WPF 3.5 和 WPF 4.0。
That is, this xaml works for both WPF 3.5 and WPF 4.0:
也就是说,这个 xaml 适用于 WPF 3.5 和 WPF 4.0:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ColorsReferencingColors.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480"
>
<Window.Resources>
<Color x:Key="DarkBlue">DarkBlue</Color>
<StaticResource x:Key="EllipseBackgroundColor" ResourceKey="DarkBlue"/>
<SolidColorBrush
x:Key="ellipseFillBrush"
Color="{DynamicResource EllipseBackgroundColor}"
/>
</Window.Resources>
<Grid>
<StackPanel Margin="25">
<Ellipse
Width="200"
Height="200"
Fill="{DynamicResource ellipseFillBrush}"
/>
</StackPanel>
</Grid>
</Window>
Another thing that bears mentioning (again) is that this approach wreaks havoc with the designers out there (i.e the Visual Studio 2008 and 2010 designers, the Blend 3 and 4 designers). I speculate that this is the same reason why Kaxaml 1.7 wasn't liking H.B.'s xaml (if you're following the comment stream on H.B.'s answer).
另一件值得(再次)提及的事情是,这种方法对那里的设计师(即 Visual Studio 2008 和 2010 设计师、Blend 3 和 4 设计师)造成了严重破坏。我推测这与 Kaxaml 1.7 不喜欢 HB 的 xaml 的原因相同(如果您正在关注 HB 回答的评论流)。
But while it breaks the designers for a simple test case, it doesn't seem to break the design surface for the large scale application I work on in my day job. Plain weird! In other words, if you care about things still working in the designer, try this method out anyway ... your designer may still work!
但是,虽然它打破了设计人员的简单测试用例,但它似乎并没有打破我在日常工作中处理的大型应用程序的设计表面。普通怪异!换句话说,如果您关心设计器中仍然有效的事情,无论如何尝试这种方法......您的设计器可能仍然有效!
回答by Erno
That last part is not possible as a Color has no Color property.
最后一部分是不可能的,因为 Color 没有 Color 属性。
A Color does have an R, G, B and A property. So you could create four bytes as resources:
A Color 确实具有 R、G、B 和 A 属性。所以你可以创建四个字节作为资源:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:Byte x:Key="r">#23</sys:Byte>
<sys:Byte x:Key="g">#45</sys:Byte>
<sys:Byte x:Key="b">#67</sys:Byte>
<sys:Byte x:Key="a">#FF</sys:Byte>
<Color x:Key="c1" R="{StaticResource r}"
G="{StaticResource g}"
B="{StaticResource b}"
A="{StaticResource a}"/>
<Color x:Key="c2" R="{StaticResource r}"
G="{StaticResource g}"
B="{StaticResource b}"
A="{StaticResource a}"/>
</ResourceDictionary>
Still not what you might prefer but it should work.
仍然不是您可能喜欢的,但它应该可以工作。