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.

HmH
  • 389
  • 3
  • 14
  • 1
    Usually, you just ensure that [CanExecute is false for that button](https://stackoverflow.com/a/3476708/87698). 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? – Heinzi Aug 27 '18 at 08:08
  • 3
    Try `RadioButton`, It's very fit for this situation – Mr. Squirrel.Downy Aug 27 '18 at 08:10
  • The problem is that all buttons are disabled, but what I want is to disable only clicked one and enable all others. – HmH Aug 27 '18 at 08:10
  • Then you'll have to have one command per button? – Haytam Aug 27 '18 at 08:13
  • You can always just add a click even on to your buttons, put them under one control for simplicity, get that control, dissable all other buttons and enable only your button – mahlatse Aug 27 '18 at 08:13
  • @HmH: Yes, I understood that. Please answer the questions in my comment, it will help us understand your requirements better. – Heinzi Aug 27 '18 at 08:16
  • What is your viewmodel structure? Any list or individual properties ? – Gaurang Dave Aug 27 '18 at 08:17
  • You can't distinguish each button from the other else in this way. Try to use at least a command parameter for each button. Give us at least the command code in the vm – Gianluca Conte Aug 27 '18 at 08:26
  • @Heinzi Yes and each one is associated with a parameter. Each button shows different page that's why I need 4 buttons, mostly it's like a dashboard. – HmH Aug 27 '18 at 12:44
  • 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. – Heinzi Aug 27 '18 at 12:49

1 Answers1

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?