Jean Tehhe
Jean Tehhe

Reputation: 1357

Change button color to white when changing windows theme to high contrast

Im using the following code and nothing happen (the button remain with orignal color) when I change the contrast to high , what I miss here? I just want to change the button color to white in high contrast mode

<Style x:Key="ButtonStyle"
           TargetType="Button">
        <Setter Property="Template"
                Value="{StaticResource ButtonBaseControlTemplate}" />
        <Setter Property="FocusVisualStyle">
            <Setter.Value>
                <Style>
                </Style>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <DataTrigger Binding="{Binding Source={x:Static SystemParameters.HighContrast}}"
                         Value="True">
                <Setter Property="Background"
                        Value="White"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

Upvotes: 3

Views: 1203

Answers (2)

Stefan Over
Stefan Over

Reputation: 6066

WPF doesn't attach to the SystemParameters.StaticPropertyChanged event. So you need to declare a wrapper that attaches to this event and passes it to the view with the PropertyChanged event. A simple implementation could look like this:

View.xaml:

<Window xmlns:app="clr-namespace:YourNamespace">
    <Window.Resources>
        <Style x:Key="HighContrastButtonStyle"
               TargetType="{x:Type Button}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Source={x:Static app:UserPrefParameters.Instance}, Path=HighContrast}"
                             Value="true">
                    <Setter Property="Background" Value="White"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Button Style="{StaticResource HighContrastButtonStyle}"
            Content="Press me!"/>
</Window>

UserPrefParameters.cs:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace YourNamespace
{
    public class UserPrefParameters : INotifyPropertyChanged
    {
        public static readonly UserPrefParameters Instance;

        public bool HighContrast
        {
            get { return SystemParameters.HighContrast; }
        }

        static UserPrefParameters()
        {
            Instance = new UserPrefParameters();
        }

        public UserPrefParameters()
        {
            SystemParameters.StaticPropertyChanged += SystemParametersOnStaticPropertyChanged;
        }

        private void SystemParametersOnStaticPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            if (args.PropertyName == "HighContrast")
                OnPropertyChanged(args.PropertyName);
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Upvotes: 2

Heena
Heena

Reputation: 8654

You need to add datatrigger inside the controltemplate

 <Button Height="35" Width="100" Content="Hello World">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="Template" Value="{DynamicResource ButtonBaseControlTemplate1}"/>
            </Style>
        </Button.Style>
        <Button.Resources>
            <ControlTemplate x:Key="ButtonBaseControlTemplate1" TargetType="{x:Type ButtonBase}">
                <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>                       
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" TargetName="border" Value="#FFBEE6FD"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="#FF3C7FB1"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" TargetName="border" Value="#FFC4E5F6"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="#FF2C628B"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Background" TargetName="border" Value="#FFF4F4F4"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="#FFADB2B5"/>
                        <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
                    </Trigger>
                    <DataTrigger Binding="{Binding Source={x:Static SystemParameters.HighContrast}}" Value="True">
                        <Setter Property="Background" Value="White"/>
                        <Setter Property="Foreground" Value="Black"/>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Button.Resources>

    </Button>

Update

I have store HighContrast Theme value in Tag.if tag property has that value then only theme is changed into HighContrast otherwise not.

     <Window.Resources>
        <!--Button ControlTemplate-->
        <ControlTemplate x:Key="ButtonBaseControlTemplate" TargetType="{x:Type ButtonBase}">
            <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" TargetName="border" Value="#FFBEE6FD"/>
                    <Setter Property="BorderBrush" TargetName="border" Value="#FF3C7FB1"/>
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter Property="Background" TargetName="border" Value="#FFC4E5F6"/>
                    <Setter Property="BorderBrush" TargetName="border" Value="#FF2C628B"/>
                </Trigger>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Background" TargetName="border" Value="#FFF4F4F4"/>
                    <Setter Property="BorderBrush" TargetName="border" Value="#FFADB2B5"/>
                    <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
                </Trigger>
                <DataTrigger Binding="{Binding RelativeSource= {x:Static RelativeSource.Self}, Path=Tag}" Value="True">
                    <Setter Property="Background" Value="White"/>
                    <Setter Property="Foreground" Value="Black"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding RelativeSource= {x:Static RelativeSource.Self}, Path=Tag}" Value="False">
                    <Setter Property="Background" Value="Gray"/>
                </DataTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

        <!--Button Style-->
        <Style x:Key="buttonstyle" TargetType="Button">
            <Setter Property="Template" Value="{StaticResource ButtonBaseControlTemplate}"/>
        </Style>

    </Window.Resources>

    <Grid>
        <Button HorizontalAlignment="Left" Height="35" Style="{StaticResource buttonstyle}" Width="100" Tag="{DynamicResource {x:Static SystemParameters.HighContrastKey}}" Content="Hello World"/>
        <Button HorizontalAlignment="Right" Height="35" Width="100" Style="{StaticResource buttonstyle}" Content="ok"></Button>
    </Grid>

Upvotes: 3

Related Questions