How to set different style for black and white high contrast mode in wpf

2.4k Views Asked by At

I use this method to set high contrast style in xaml:

 <DataTrigger Binding="{Binding Source={x:Static SystemParameters.HighContrast}}" Value="True">
   ...                    
 </DataTrigger>

But there're two main high contrast mode, black and white, how to set style for these two mode seperately?

1

There are 1 best solutions below

0
On

I have a method that it can verify high contrast white and high contrast black. It work well in my project. I hope it can help you.

First, need new a DependencyProperty to judge if it is white or black.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace Views.Styles
{
    public class HighConstrastWhite : DependencyObject
    {
    #region Singleton pattern

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


        private static HighConstrastWhite _instance;


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

                return _instance;
            }
        }

    #endregion

    public void ApplyCurrentTheme()
    {  
        if(SystemParameters.HighContrast)
        {
            SolidColorBrush windowbrush = SystemColors.WindowBrush;
            if (windowbrush.Color.R == 255 && windowbrush.Color.G == 255 && windowbrush.Color.B == 255)
                HighConstrastWhite.Instance.IsHighContrastWhite = true;
            else
                HighConstrastWhite.Instance.IsHighContrastWhite = false;
        }
    }

    void SystemParameters_StaticPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        //Console.WriteLine(e.PropertyName);
        if (e.PropertyName == "HighContrast")
        {
            ApplyCurrentTheme();
        }

    }


    #region DP IsHighContrast

    public static readonly DependencyProperty IsHighContrastWhiteProperty = DependencyProperty.Register(
        "IsHighContrastWhite",
        typeof(bool),
        typeof(HighConstrastWhite),
        new PropertyMetadata(
            false
            ));


    public bool IsHighContrastWhite
    {
        get { return (bool)GetValue(IsHighContrastWhiteProperty); }
        private set { SetValue(IsHighContrastWhiteProperty, value); }
    }

    #endregion

}
}

Second, you can use it in trigger. But you do best to use it with SystemParameters.HighContrast. For example:

    ...
xmlns:style="clr-namespace:Views.Styles"
...


<Style x:Key="FindTextImageButtonStyle" TargetType="controls:ImageButton" BasedOn="{StaticResource FunctionImageButtonStyle}">
        <Setter Property="BorderThickness" Value="0,0,1,0"/>
        <Setter Property="NormalImage" Value="pack://application:,,,/App;component/Assets/Images/Find.png"/>
        <Setter Property="OverImage" Value="pack://application:,,,/App;component/Assets/Images/Find.png"/>
        <Setter Property="PressedImage" Value="pack://application:,,,/App;component/Assets/Images/Find_Pressed.png"/>
        <Setter Property="DisableImage" Value="pack://application:,,,/App;component/Assets/Images/Find_Disable.png"/>
        <Setter Property="Tag" Value="{DynamicResource {x:Static SystemParameters.HighContrastKey}}"/>
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=IsHighContrastWhite, Source={x:Static style:HighConstrastWhite.Instance}}" Value="True" />
                    <Condition  Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" Value="true"/>
            </MultiDataTrigger.Conditions>
                <Setter Property="NormalImage" Value="pack://application:,,,/App;component/Assets/Images/Find.scale-100_contrast-white.png"/>
                <Setter Property="OverImage" Value="pack://application:,,,/App;component/Assets/Images/Find.scale-100_contrast-white.png"/>
                <Setter Property="PressedImage" Value="pack://application:,,,/App;component/Assets/Images/Find_Pressed.scale-100_contrast-white.png"/>
                <Setter Property="DisableImage" Value="pack://application:,,,/App;component/Assets/Images/Find_Disable.png"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=IsHighContrastWhite, Source={x:Static style:HighConstrastWhite.Instance}}" Value="False" />
                    <Condition  Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" Value="true"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="NormalImage" Value="pack://application:,,,/App;component/Assets/Images/Find.scale-100_contrast-black.png"/>
                <Setter Property="OverImage" Value="pack://application:,,,/App;component/Assets/Images/Find.scale-100_contrast-black.png"/>
                <Setter Property="PressedImage" Value="pack://application:,,,/App;component/Assets/Images/Find_Pressed.scale-100_contrast-black.png"/>
                <Setter Property="DisableImage" Value="pack://application:,,,/App;component/Assets/Images/Find_Disable.png"/>
            </MultiDataTrigger>
        </Style.Triggers>


    </Style>

By the way, For startup your app correctly in the high contrast theme, you need add code in your MainWindow.xaml.cs to trigger manually.

...
public MainWindow()
        {
            HighConstrastWhite.Instance.ApplyCurrentTheme();
...