根据背景颜色选择合适的前景的样式

|| 我有一个WPF应用程序,该应用程序附带了由项目类型定义的Label,TextBox等默认样式集(未定义显式键)。 在该应用程序中,使用了两个主要容器,一个使用深色背景,另一个使用浅色背景,因此有时使用黑色作为Label的前景色是正确的,有时则是非常错误的。另一方面,编辑器总是在传统上使用浅色背景和深色前景进行样式设置,因此我不能仅将所有子元素的前景设置为相反的。 有没有一种优雅的方法可以使我的标签(可能还有TextBlocks)决定依赖于“其”背景的前景色?我只想在两种颜色之间切换,因此不需要自动对比度最大化,只需要一个阈值就可以避免白色底色上的白色字体。 我也不想定义两组默认​​样式,因此我强烈寻求某种方式使我的单个Label-Default-Style适用于两种背景变体。 是否可以(并且在不影响性能的前提下)向样式添加触发器/绑定,以评估当前的背景色? 另外,我将对最佳做法感兴趣,如何在不遇到上述问题的情况下,为某些FrameworkElement(尤其是容器/面板)设置干净的背景色。 这是我尝试过的(当然是简化的):
  <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 \”),不是。 我很乐意让样式能够评估“有效背景”(无论它来自何处)并为此背景选择适当的前景画笔。     
已邀请:
        这个问题似乎暗示着一个更深层次的问题。我猜您尚未合并前景色的管理,因此您有一个应用程序,该应用程序具有在各处设置前景色的代码或样式。现在,您正在处理其中的一种含义。 我将面对更深层次的问题并解决该问题。我不太了解为什么您不赞成创建默认样式,但是暂时假设您有充分的理由不这样做(“ \”我应该在某个时候创建​​默认样式,但现在我还没有,而且我的应用程序变大了,这太难了,”(在这种情况下,我有不同的建议)如何创建全局资源? 在应用程序的资源字典中为控件的前景色和背景色创建对象,并修复XAML,以便它使用directly1ѭ标记扩展名从资源字典中获取它们,而不是直接引用画笔。在代码中,不要将控件上的
Foreground
属性直接设置为画笔,而是使用
GetResource
获取画笔。并以相同方式设置背景。 完成此操作后,如果要在应用程序中全局更改前景色/背景色,则只需更改资源。 基本上,这就是开始使WPF应用程序可换肤的方式,这似乎是您要走的路。     
        最简单的方法是将TextBoxes等的前景色绑定到其包含元素的背景,然后使用值转换器进行更改。如果您仅使用两种颜色,则这特别容易。 举个例子....
  public class ColorSwapper : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, 
System.Globalization.CultureInfo culture)
    {
      if (value == null) { return DependencyProperty.UnsetValue; }

      Color srcColor = (value as SolidColorBrush).Color;
      if (srcColor == Colors.Black)
      {
        return new SolidColorBrush(Colors.White);
      }
      else
      {
        return new SolidColorBrush(Colors.Black);
      }
    }
...
还有一些示例XAML ...
<Grid Grid.Column=\"1\" Name=\"RightGrid\" Background=\"White\">
  <TextBlock Text=\"Hello Nurse!\" Foreground=\"{Binding ElementName=RightGrid, Path=Background, Converter={StaticResource ColorSwapper}}\"/>
</Grid>
当然,您可能会希望根据自己的特定需求进行一些调整和清理,但这可以做到。     
        这是另一种可能的方法。如果您的应用程序仅具有所有深色/浅色背景及其修饰,则可以使用我在其他答案中提到的\'ColorSwapper \',尝试使用这种方法。
<Window>
  <Window.Resources>
    <local:ColorSwapper x:Key=\"swapper\"/>

    <SolidColorBrush x:Key=\"BackBrush\" Color=\"Black\"/>
    <!--<SolidColorBrush x:Key=\"BackBrush\" Color=\"White\"/>-->

    <Style TargetType=\"{x:Type TextBlock}\">
      <Setter Property=\"Foreground\" Value=\"{Binding Source={StaticResource BackBrush}, Converter={StaticResource swapper}}\"/>
    </Style>

  </Window.Resources>

  <Grid Background=\"{StaticResource BackBrush}\">
    <TextBlock FontSize=\"24\" FontWeight=\"Bold\">ABC</TextBlock>
  </Grid>
</Window>
现在,无论何时更改\'BackBrush \'的颜色值,所有相关的前景色都会自动更新。根据您的讨论,我认为这也将满足您的样式要求。无论如何,您可能必须制作小型mod,以确保此方法适合您的实际情况。     

要回复问题请先登录注册