如何在WPF中恢复高对比度颜色?

时间:2013-09-09 23:53:53

标签: wpf xaml

我有一些直接设置前景色的XAML:

<Style x:Key="HomeHeaderText" TargetType="TextBlock">
    <Setter Property="FontSize" Value="24" />
    <Setter Property="FontFamily" Value="Segoe Light UI" />
    <Setter Property="Foreground" Value="#FF606060" />
    <Setter Property="Margin" Value="0,50,0,30" />
</Style>

我想在风格中检测系统是否处于高对比度模式,如果是,则回退到系统颜色之一。

如何使用样式做到这一点?


我尝试使用触发器进行设置,但这会在运行时生成XamlParseException

<Style x:Key="HomeHeaderText" TargetType="TextBlock">
    <Setter Property="FontSize" Value="24" />
    <Setter Property="FontFamily" Value="Segoe Light UI" />
    <Setter Property="Foreground" Value="#FF606060" />
    <Setter Property="Margin" Value="0,50,0,30" />
    <Style.Triggers>
        <DataTrigger Binding="{x:Static SystemParameters.HighContrast}" Value="True">
           <Setter Property="Foreground"
               Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

3 个答案:

答案 0 :(得分:9)

您尝试的问题是DataTrigger.Binding想要绑定,但您给它一个直接值。您可以通过设置绑定源来解决此问题:

{Binding Source={x:Static SystemParameters.HighContrast}}

但是,这不会是动态的 - 如果有人在应用程序运行时切换高对比度,则样式不会更新。理想情况下,拥有这样的东西会很好:

{Binding Source={x:Static SystemParameters}, Path=HighContrast}

但不幸的是,这是不可能的,因为它是一个静态属性。因此,绑定到HighContrastKey资源是更好的选择。您可以将此绑定到附加属性,而不是使用Tag。想想看,微软可能应该首先将SystemParameters作为附加属性实现。尝试这样的事情:

public static class SystemParameterProperties {
    public static readonly DependencyProperty HighContrastProperty =
        DependencyProperty.RegisterAttached("HighContrast", typeof(bool), typeof(SystemParameterProperties),
            new FrameworkPropertyMetadata() {Inherits = true});

    public static bool GetHighContrast(DependencyObject obj) {
        return (bool)obj.GetValue(HighContrastProperty);
    }

    public static void SetHighContrast(DependencyObject obj, bool value) {
        obj.SetValue(HighContrastProperty, value);
    }
}

我在属性上使用了Inherits = true,这样我们就可以将它设置在最外层的容器上,让它随处可访问,即:

<Window ...
        xmlns:attachedProperties="..."
        attachedProperties:SystemParameterProperties.HighContrast="{DynamicResource ResourceKey={x:Static Member=SystemParameters.HighContrastKey}}">
    ...
</Window>

最后,您的触发器将是:

<Trigger Property="attachedProperties:SystemParameterProperties.HighContrast" Value="True">
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</Trigger>

答案 1 :(得分:3)

我已经解决了利用助手的问题:

public class HighContrastHelper
    : DependencyObject
{
    #region Singleton pattern

    private HighContrastHelper()
    {
        SystemParameters.StaticPropertyChanged += SystemParameters_StaticPropertyChanged;
    }

    private static HighContrastHelper _instance;

    public static HighContrastHelper Instance
    {
        get
        {
            if (_instance == null)
                _instance = new HighContrastHelper();

            return _instance;
        }
    }

    #endregion

    void SystemParameters_StaticPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine(e.PropertyName);
        if (e.PropertyName == "HighContrast")
        {
            HighContrastHelper.Instance.IsHighContrast = SystemParameters.HighContrast;
        }
    }

    #region DP IsHighContrast

    public static readonly DependencyProperty IsHighContrastProperty = DependencyProperty.Register(
        "IsHighContrast",
        typeof(bool),
        typeof(HighContrastHelper),
        new PropertyMetadata(
            false
            ));

    public bool IsHighContrast
    {
        get { return (bool)GetValue(IsHighContrastProperty); }
        private set { SetValue(IsHighContrastProperty, value); }
    }

    #endregion  
 }

之后,代码中的用法非常简单:

<Style x:Key="HomeHeaderText" TargetType="TextBlock">
    <Setter Property="FontSize" Value="24" />
    <Setter Property="FontFamily" Value="Segoe Light UI" />
    <Setter Property="Foreground" Value="#FF606060" />
    <Setter Property="Margin" Value="0,50,0,30" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsHighContrast, Source={x:Static local:HighContrastHelper.Instance}}" Value="True">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

希望它有所帮助。

答案 2 :(得分:1)

您可以将其绑定到textblock的Tag属性,并在DataTrigger中使用它,如下所示:

  <Style x:Key="MyTextBoxStyle" TargetType="{x:Type TextBlock}">
     <Setter Property="Tag" Value="{DynamicResource {x:Static SystemParameters.HighContrastKey}}"/>
     <Style.Triggers>
         <DataTrigger Binding="{Binding Path=Tag , RelativeSource= {x:Static RelativeSource.Self}}" Value="True">
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
         </DataTrigger>
     </Style.Triggers>
  </Style>