根据背景颜色选择合适的前景的样式 [英] Style to choose suitable foreground according to background color

查看:106
本文介绍了根据背景颜色选择合适的前景的样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF应用程序,该应用程序附带了由项目类型定义的Label,TextBox等默认样式集(未定义显式键).

I have a WPF application which ships with a set of default styles for Label, TextBox etc. defined by item types (no explicit keys defined).

在该应用程序中,使用了两个主要容器,一个带有深色背景,另一个带有浅色背景,因此有时使用黑色作为Label的前景色是正确的,有时则是非常错误的.另一方面,编辑器总是在传统上使用浅色背景和深色前景进行样式设置,因此我不能仅将所有子元素的前景设置为相反的颜色.

Within the application there are two main containers used, one with dark background and one with light background, such that sometimes it's right to use black as the foreground color for a Label and sometimes its dramatically wrong. On the other hand, editors are always styled rather traditionally with light background and dark foreground, so I cannot just set the foreground for all child elements to the inverse.

是否有一种优雅的方法可以使我的标签(可能还有TextBlocks)决定依赖于其"背景的前景色?我只想在两种颜色之间切换,因此不需要自动对比度最大化,只需要一个阈值就可以避免白色底色上的白色字体.

Is there an elegant way to make my labels (and maybe TextBlocks as well) to decide about their foreground color dependent on 'their' background? I only want to switch between two colors, thus no auto-contrast-maximization needed, only some threshold to avoid white font on white ground.

我也不想定义两组默认​​样式,我强烈寻求某种方式使我的单个Label-Default-Style适用于两种背景变体.

I also don't want to define two sets of default styles, I strongly search for some way to make my single Label-Default-Style be appropriate for both background variants.

是否可以(并且在不影响性能的前提下)向样式添加触发器/绑定,以评估当前的背景色?

Is it possible (and feasible without too much performance hit) to add a trigger/binding to the style, which evaluates the current background color?

或者,我将对如何为某些FrameworkElement(尤其是容器/面板)干净地设置背景色而不会遇到上述问题的最佳实践感兴趣.

Alternatively, I would be interested in best practices how to cleanly set background-colors for certain FrameworkElements, especially containers/panels, without running into the problems described above.

这是我尝试过的(当然是简化的):

Here is what I tried (simplified of course):

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

如果Label具有明确的背景设置(x:Name = bgSetExplicitly),但是如果背景是从VisualTree的父级继承"的,则可以看到标签的背景被很好地选择了. bgInheritedFromParent),不是. 我很乐意让样式能够评估有效背景"(无论它来自何处)并为此背景选择合适的前景画笔.

You can see that the label's background is chosen nicely, if the Label has an explicit background set (x:Name=bgSetExplicitly), but if the background is 'inherited' from the parent in the VisualTree (x:Name="bgInheritedFromParent"), it's not. I would love to have that working that the style can evaluate the "effective background" (no matter where it comes from) and choose an appropriate foreeground-brush for this background.

推荐答案

这个问题似乎暗示着一个更深层次的问题.我猜您尚未合并前景色的管理,因此您拥有一个应用程序,该应用程序具有在各处设置前景色的代码或样式.现在您正在处理其中的一种含义.

This question seems to imply a deeper issue. I would guess that you haven't consolidated the management of foreground colors, and so you have an application that has code or styles that set foreground colors all over the place. And now you're dealing with one of the implications of that.

我将面对更深层次的问题并解决该问题.我真的不明白为什么您会拒绝创建默认样式的想法,但是暂时假设您有充分的理由不这样做(除了我应该在某个时候创建​​默认样式,但现在我还没有,而且我的应用程序变大了,这太难了."在这种情况下,我有不同的建议)如何创建全局资源?

I'd face the deeper issue and fix that. I don't really understand why you're resistant to the idea of creating default styles, but assuming for the moment that you have a good reason not to do this (other than "I should have created default styles at some point, but now that I haven't and my application has gotten big, it's just too hard," in which case, I have a different suggestion), how about creating global resources?

在应用程序的资源字典中为控件的前景色和背景色创建对象,并修复XAML,以便它使用DynamicResource标记扩展名从资源字典中获取它们,而不是直接引用画笔.在代码中,不是直接将控件上的Foreground属性设置为画笔,而是使用GetResource来获取画笔.并以相同的方式设置背景.

Create objects in the application's resource dictionary for the controls' foreground and background colors, and fix the XAML so that instead of referencing brushes directly, it uses the DynamicResource markup extension to get them from the resource dictionary. In code, instead of setting the Foreground property on the controls to a brush directly, use GetResource to get the brush. And set the background the same way.

完成此操作后,如果要在应用程序中全局更改前景色/背景色,则只需更改资源即可.

Once you've done this, if you want to change foreground/background colors globally in your application, you just change the resources.

基本上,这就是开始使WPF应用程序可换肤的方式,这似乎是您要走的路.

This is basically how you start making a WPF application skinnable, which seems to be the road you're going down.

这篇关于根据背景颜色选择合适的前景的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆