2

I have a group of buttons that are enabled whenever one of the buttons is clicked and the clicked one is disabled.

<Button DockPanel.Dock="Top" Style="{StaticResource BigGrayButton}" Command="{Binding Path=NavigatePage}" IsEnabled="{Binding Path=EnableButton}"/>
<Button DockPanel.Dock="Top" Style="{StaticResource BigGrayButton}" Command="{Binding Path=NavigatePage}" IsEnabled="{Binding Path=EnableButton}"/>
<Button DockPanel.Dock="Top" Style="{StaticResource BigGrayButton}" Command="{Binding Path=NavigatePage}" IsEnabled="{Binding Path=EnableButton}"/>
<Button DockPanel.Dock="Top" Style="{StaticResource BigGrayButton}" Command="{Binding Path=NavigatePage}" IsEnabled="{Binding Path=EnableButton}"/>

The problem is using the above code result in disabling all buttons when setting EnableButton to false after executing the command.

10
  • 1
    Usually, you just ensure that CanExecute is false for that button. Do you really have the same command bound to all the buttons? If yes, how do you determine which one was clicked (because, I assume that it makes a difference to your app)? If all the buttons are exactly the same, why do you have 4 of them instead of 1? Commented Aug 27, 2018 at 8:08
  • 3
    Try RadioButton, It's very fit for this situation Commented Aug 27, 2018 at 8:10
  • The problem is that all buttons are disabled, but what I want is to disable only clicked one and enable all others. Commented Aug 27, 2018 at 8:10
  • Then you'll have to have one command per button? Commented Aug 27, 2018 at 8:13
  • 1
    @HmH: Ah, I see, so the buttons are basically toggle buttons for choosing the page to be shown, right? In that case, the easiest solution would be to have CanExecute return false, if the parameter equals the currently shown page, and true otherwise. You won't need IsEnabled at all. Commented Aug 27, 2018 at 12:49

1 Answer 1

7

As I said, why not try RadioButton?

If you only want to achieve this "feature", this is too easy - even don't need involve MVVM

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <StackPanel.Resources>
        <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="#FFF4F4F4"/>
        <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
        <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
        <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>
        <Style x:Key="BaseButtonStyle" TargetType="{x:Type RadioButton}">
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="true">
                    <Setter Property="IsEnabled" Value="False"/>
                </Trigger>
            </Style.Triggers>
            <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
            <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
            <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Padding" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <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>
    </StackPanel.Resources>
    <RadioButton Content="Button1" Style="{StaticResource BaseButtonStyle}"/>
    <RadioButton Content="Button2" Style="{StaticResource BaseButtonStyle}"/>
    <RadioButton Content="Button3" Style="{StaticResource BaseButtonStyle}"/>
    <RadioButton Content="Button4" Style="{StaticResource BaseButtonStyle}"/>
</StackPanel>

Preview:


Then you can setting CommandParameter for each button to tell the backend code which button was pressed.

You don't need to write any complicated logic to implement this feature. Why not try it?

Sign up to request clarification or add additional context in comments.

4 Comments

+1 because this doesn't require writing out the custom logic because it's already implemented, and it allows for easy styling.
It seems the best solution with minimum code, even though I'm still looking to implement this behavior with regular button using mvvm.
Here has a car, why you need to reinvent the wheel? :-)
For some more: if you acturaly want to use MVVM, try to write a style on ListBox

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.