【发布时间】:2011-09-05 09:26:02
【问题描述】:
我有一个 WPF 应用程序,它附带一组由项目类型定义的标签、文本框等默认样式(未定义显式键)。
在应用程序中使用了两种主要容器,一种具有深色背景,另一种具有浅色背景,因此有时使用黑色作为标签的前景色是正确的,有时则严重错误。另一方面,编辑器的样式总是比较传统的浅色背景和深色前景,所以我不能只将所有子元素的前景设置为相反。
有没有一种优雅的方法可以让我的标签(也许还有 TextBlocks)根据“他们的”背景来决定他们的前景色?我只想在两种颜色之间切换,因此不需要自动对比度最大化,只需要一些阈值来避免白底上的白色字体。
我也不想定义两组默认样式,我强烈寻找某种方法使我的单个 Label-Default-Style 适合两种背景变体。
是否有可能(并且在没有太多性能损失的情况下可行)向样式添加触发器/绑定以评估当前背景颜色?
另外,我对如何为某些 FrameworkElements(尤其是容器/面板)干净地设置背景颜色而不遇到上述问题的最佳实践感兴趣。
这是我尝试过的(当然是简化的):
<UniformGrid>
<UniformGrid.Resources>
<!-- SimpleStyles: Label -->
<Style x:Key="{x:Type Label}" TargetType="{x:Type Label}">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Border>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Background" Value="Black">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UniformGrid.Resources>
<Label x:Name="bgSetExplicitly" Background="Black">abc
</Label>
<Border Background="Black">
<Label x:Name="bgInheritedFromParent" >abc
</Label>
</Border>
<Label>abc
</Label>
<Label>abc
</Label>
如果标签具有显式背景集 (x:Name=bgSetExplicitly),但如果背景是从 VisualTree 中的父级“继承”的 (x:Name=" bgInheritedFromParent"),它不是。 我希望该样式可以评估“有效背景”(无论它来自何处)并为此背景选择合适的前景画笔。
【问题讨论】:
-
我终于接受了罗伯特的建议:每个设置自定义背景的容器也必须设置一个合适的前景。所有控件(标签,文本框等)都必须尊重这些设置,s.th。无论将 TextBox 放在哪个容器中,它都会看起来不错。最初,我试图找到一个解决方案,即使应用程序中的某些样式不遵循该规则也可以工作,主要是为了稳健性,因为我们无法在每次更改基本样式后对所有对话框进行运行时测试。但事实证明这比我最初想象的要困难,所以我暂时放弃了。
标签: wpf styles background-color foreground