简体   繁体   中英

WPF Button Background Change on Click and Reset to original when another button in same StackPanel Clicked.

I have a StackPanel with a few buttons. I want to change the color of a button when clicked and reset it to the original when another button in StackPanel is clicked. Is it possible with a single style applied on StackPanel or I have to create Style for each button? If yes then how.

Here is the code of Style applied to StackPanel but this changes the color of the button but does not reset it on clicking another button.

<Style TargetType="StackPanel" x:Key="GlobalStackPanelStyle" BasedOn="{StaticResource FlatStackPanel}">
      <Style.Resources>
            <Style TargetType="Button">
                <Setter Property="Button.Background" Value="Blue"/>
                <Style.Triggers> 
                    <Trigger Property="IsPressed" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="Green"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>                           
                    </Trigger>                        
                </Style.Triggers>
            </Style>
        </Style.Resources>
    </Style>

Sorry for the delayed response. Here are the steps that you can follow to get the required output.

Assuming you are following MVVM design pattern.

  1. Create buttons in .xaml and bind command to each button as shown below,

     <Button Height="32" Width="180" Grid.Column="1" Content="Button 1" Command="{Binding ClickCommand}" CommandParameter="Button 1"> <Button.Style> <Style TargetType="{x:Type Button}"> <Style.Triggers> <DataTrigger Binding="{Binding IsButton1Active}" Value="True"> <Setter Property="Background" Value="Green" /> <Setter Property="Foreground" Value="White" /> </DataTrigger> <DataTrigger Binding="{Binding IsButton1Active}" Value="False"> <Setter Property="Background" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button> <Button Height="32" Width="180" Grid.Column="2" Content="Button 2" Margin="5,0,0,0" Command="{Binding ClickCommand}" CommandParameter="Button 2"> <Button.Style> <Style TargetType="{x:Type Button}"> <Style.Triggers> <DataTrigger Binding="{Binding IsButton2Active}" Value="True"> <Setter Property="Background" Value="Green" /> <Setter Property="Foreground" Value="White" /> </DataTrigger> <DataTrigger Binding="{Binding IsButton2Active}" Value="False"> <Setter Property="Background" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button>

Note: You can add how many buttons you want to add to above xaml.

  1. Create 2 boolean properties and set the values of those boolean properties from your ClickCommand method.

     private bool isButton1Active; private bool isButton2Active; public bool IsButton1Active { get { return isButton1Active; } set { isButton1Active = value; OnPropertyChanged(); } } public bool IsButton2Active { get { return isButton2Active; } set { isButton2Active = value; OnPropertyChanged(); } }
  2. Here is code for command - Add it in your ViewModel

     private UICommand _clickCommand; public UICommand ClickCommand { get { return _clickCommand; } }
  3. Write below statement in your view model constructor

     public YourViewModelConstructor() { _clickCommand = new UICommand(OnClick); }
  4. Here is the method that is bound to ClickCommand

     private void OnClick(object parameter) { switch(parameter.ToString()) { case "Button 1": IsButton1Active = true; IsButton2Active = false; break; case "Button 2": IsButton2Active = true; IsButton1Active = false; break; } }
  5. Here is the code for my UICommand class

     public class UICommand : ICommand { private readonly Action<object> _execute; private readonly Func<bool> _canExecute; public UICommand(Action<object> onExecuteMethod, Func<bool> onCanExecuteMethod = null) { _execute = onExecuteMethod; _canExecute = onCanExecuteMethod; } public bool IsCanExecute { get; set; } #region ICommand Members public event EventHandler CanExecuteChanged { add { if (_canExecute != null) CommandManager.RequerySuggested += value; } remove { if (_canExecute != null) CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { _execute(parameter); } public bool CanExecute(object parameter) { IsCanExecute = (_canExecute == null || _canExecute()); return IsCanExecute; } #endregion public void RaiseCanExecuteChanged() { CommandManager.InvalidateRequerySuggested(); } }

I assume you know on how to setting datacontext to your window.

This examples gives you an idea on how to achieve functionality by creating some properties created in your ViewModel and bind a command in your View to ViewModel Command property and invoke click command by passing Command Parameter.

Still have any doubts after implementing the solution, kindly let us know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM