Search code examples
c#wpfxamlmvvmmvvm-light

Change button property when IsEnabled change in wpf


I have a button in my view with style in staticResource. I have IsEnabled bind to a bool in my viewmodel and want to change background when is disable.

I tried to use Style.Triggers on IsEnabled = false but this don't change the background.

Styles.xaml

  <Style x:Key="buttonNegative" TargetType="Button">
    <Style.Triggers>
      <Trigger Property="IsEnabled" Value="False">
        <Setter Property="Background" Value="Green"/>
      </Trigger>
    </Style.Triggers>
  </Style>

view.xaml

  <Button Style="{StaticResource buttonNegative}" Command="{Binding InversionAxis_Command}" IsEnabled="{Binding SettingsButtonIsEnable}">
    <TextBlock Text="{Binding Orientation}"/>
  </Button>

viewModel.cs

private bool _settingsButtonIsEnable;
public bool SettingsButtonIsEnable
{
    get { return _settingsButtonIsEnable; }
    set
    {
        if (Equals(value, _settingsButtonIsEnable)) return;
        _settingsButtonIsEnable = value;
        RaisePropertyChanged();
    }
}

public ICommand InversionAxis_Command
{
    get { return new RelayCommand(InversionAxis, IsSettingsButtonIsEnable); }
}

private bool IsSettingsButtonIsEnable()
{
    return _settingsButtonIsEnable;
}

The command was not execute because I use canExecute but the style not changing when SettingsButtonIsEnable change


Solution

  • It's more complicated to change the disabled background than adding a trigger to the style. You'll have to define a custom ControlTemplate:

    <Style x:Key="buttonNegative" TargetType="Button">
        <Style.Resources>
            <Style x:Key="FocusVisual">
                <Setter Property="Control.Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
            <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
            <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
            <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
            <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
            <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
            <SolidColorBrush x:Key="Button.Disabled.Background" Color="Green"/>
            <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
            <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
        </Style.Resources>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                        <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsDefaulted" Value="true">
                            <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
                            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
                            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                            <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    The default disabled background is hardcoded into the default template and cannot be overridden with a style setter.