NiceDevelopmentq
NiceDevelopmentq

Reputation: 525

WPF IsMouseOver and background change on click

I'm fairly new to WPF and I'm trying to make a row of buttons, where when you hover over them they get a Red background color, and when clicked the button you clicked on's background get set to red.

I've got this working, only issue now is that the buttons don't have the IsMouseOver feature anymore after a button has been clicked.

App.xaml

<Style x:Key="MenuButton" TargetType="{x:Type Button}">
        <Setter Property="Background" Value="#373442" />
        <Setter Property="Foreground" Value="White" />
        <Setter Property="FontSize" Value="15" />
        <Setter Property="SnapsToDevicePixels" Value="True" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border CornerRadius="0" Background="{TemplateBinding Background}">
                        <Grid>
                            <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="15px"/>
                        </Grid>
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="#F06060" />
                            <Setter Property="Foreground" Value="White" />
                        </Trigger>

                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Background" Value="#F06060" />
                            <Setter Property="Foreground" Value="White" />
                        </Trigger>

                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Button XAML

<Button Style="{StaticResource ResourceKey=MenuButton}" Content="Logout" HorizontalAlignment="Left" VerticalAlignment="Top" Width="201" Height="58" Margin="0,315,0,0"/>

C# Code

public static Button[] buttonArray = new Button[3];

        public TaskManager()
        {
            InitializeComponent();

            buttonArray[0] = HomeButton;
            buttonArray[1] = TasksButton;
            buttonArray[2] = AdminButton;
        }

        public static void paneSwitcher(Button button)
        {

            foreach (Button aButton in buttonArray)
            {
                aButton.Background = Brushes.Red;
            }

            button.Background = new SolidColorBrush(Color.FromArgb(255, 240, 96, 96));
        }

        private void HomeButton_Click(object sender, RoutedEventArgs e)
        {
            paneSwitcher(HomeButton);
        }

        private void TasksButton_Click(object sender, RoutedEventArgs e)
        {
            paneSwitcher(TasksButton);
        }

        private void AdminButton_Click(object sender, RoutedEventArgs e)
        {
            paneSwitcher(AdminButton);
        }

Upvotes: 1

Views: 834

Answers (2)

mm8
mm8

Reputation: 169400

You could replace the Button with a ToggleButton that has an additional IsChecked state.

Then you could simply add another trigger to your ControlTemplate to change the colour of the Button when it's clicked:

<Style x:Key="MenuButton" TargetType="{x:Type ToggleButton}">
    <Setter Property="Background" Value="#373442" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="FontSize" Value="15" />
    <Setter Property="SnapsToDevicePixels" Value="True" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border CornerRadius="0" Background="{TemplateBinding Background}">
                    <Grid>
                        <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" 
                                                  HorizontalAlignment="Left" VerticalAlignment="Center" Margin="15px"/>
                    </Grid>
                </Border>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter Property="Background" Value="Blue" />
                        <Setter Property="Foreground" Value="White" />
                    </Trigger>

                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#F06060" />
                        <Setter Property="Foreground" Value="White" />
                    </Trigger>

                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" Value="#F06060" />
                        <Setter Property="Foreground" Value="White" />
                    </Trigger>

                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Button XAML

<ToggleButton Style="{StaticResource ResourceKey=MenuButton}" Content="Logout" HorizontalAlignment="Left" VerticalAlignment="Top" Width="201" Height="58" />

Upvotes: 1

Arie
Arie

Reputation: 5373

I propose a slightly different approach.

How about instead of painstakingly managing set of Buttons, use a group of RadioButtons styled as ToggleButtons?

Style:

 <Style TargetType="RadioButton" 
               BasedOn="{StaticResource {x:Type ToggleButton}}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate  TargetType="{x:Type RadioButton}">
                    <Border CornerRadius="0" Margin="1"
                            Background="{TemplateBinding Background}">
                        <ContentPresenter x:Name="MyContentPresenter" 
                                         Content="{TemplateBinding Content}" 
                                         HorizontalAlignment="Left" 
                                         VerticalAlignment="Center" Margin="5"/>
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="RadioButton.IsChecked" Value="True">
                            <Setter Property="Background" Value="Red" />
                            <Setter Property="Foreground" Value="White" />
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="#F06060" />
                            <Setter Property="Foreground" Value="White" />
                        </Trigger>

                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Then use it:

<UniformGrid Height="100" Width="100" VerticalAlignment="Top" Rows="3">
            <RadioButton  Content="AAA" GroupName="MY_GROUP"
                          Command="{Binding RbChecked, Mode=OneTime}"
                          CommandParameter="A"/>
            <RadioButton  Content="BBB" GroupName="MY_GROUP"
                          Command="{Binding RbChecked, Mode=OneTime}"
                          CommandParameter="B"/>
            <RadioButton  Content="CCC" GroupName="MY_GROUP"
                          Command="{Binding RbChecked, Mode=OneTime}"
                          CommandParameter="C"/>
        </UniformGrid>

Example Command implementation in the class that is your DataContext:

    private ICommand _RbChecked;

    public ICommand RbChecked
    {
        get { return _RbChecked ?? (_RbChecked = new RelayCommand<object>(a => RbCheckedCommand(a))); }
    }

    private void RbCheckedCommand(object item)
    {
        this.CurrentChosen = (string)item;
    }

Upvotes: 0

Related Questions