Reputation: 209
I am trying to change to color of button when clicked. It is taking the initial color assigned but not updating when clicked. I attaching my code, let me know where I am going wrong. I tried to implement the code provided in the following post
MainWindow.xaml snippet
<Window.Resources>
<viewModels:MainWindowViewModel x:Key="MainViewModel"/>
</Window.Resources>
<Border Padding="20">
<StackPanel DataContext="{Binding Source={StaticResource MainViewModel}}">
<Button Content="Button1" Margin="10 10 10 10" Command="{Binding ClickCommand, Mode=OneWay}" Background="{Binding BackgroundColorBtn1}"/>
<Button Content="Button2 " Margin="10 10 10 10"></Button>
</StackPanel>
</Border>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
var desktopWorkingArea = System.Windows.SystemParameters.WorkArea;
this.Left = desktopWorkingArea.Right - this.Width;
this.Top = desktopWorkingArea.Bottom - this.Height;
}
}
MainWindowViewModel.cs
namespace DockedPanel.ViewModels
{
public class MainWindowViewModel:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MainWindowViewModel()
{
_canExecute = true;
}
private ICommand _clickCommand;
public ICommand ClickCommand
{
get
{
return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), _canExecute));
}
}
private bool _canExecute;
public void MyAction()
{
_backgroundColorBtn1 = Colors.Blue;
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private Color _backgroundColorBtn1 = Colors.White;
public Color BackgroundColorBtn1
{
get { return _backgroundColorBtn1; }
set
{
if (value == _backgroundColorBtn1)
return;
_backgroundColorBtn1 = value;
OnPropertyChanged(nameof(BackgroundColorBtn1));
}
}
}
}
and finally CommandHandler
namespace DockedPanel.ViewModels.Command
{
public class CommandHandler : ICommand
{
private Action _action;
private bool _canExecute;
public CommandHandler(Action action, bool canExecute)
{
_action = action;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action();
}
}
}
Upvotes: 1
Views: 2588
Reputation: 18155
You need to call OnPropertyChanged on the BackgroundColorBtn1 property since you are changing the private backing variable, and the View needs to be notified.
You can modify your MyAction method as following
public void MyAction()
{
_backgroundColorBtn1 = Colors.Blue;
OnPropertyChanged(nameof(BackgroundColorBtn1));
}
Alternatively, you could set the Property directly instead of backing field, which would invoke the OnPropertyChanged call itself.
public void MyAction()
{
BackgroundColorBtn1 = Colors.Blue;
}
You would also need to use a Color To Brush Converter. The background property of button accepts Brush, not color. The convertor would allow you to convert the chosen Color to Brush.
You can define the Converter as following
public class ColorToSolidColorBrushValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
if (value is Color)
return new SolidColorBrush((Color)value);
throw new InvalidOperationException("Unsupported type [" + value.GetType().Name + "], ColorToSolidColorBrushValueConverter.Convert()");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
And then, you can use it as
Background="{Binding BackgroundColorBtn1, Converter={StaticResource colorToSolidColorBrushConverter}}"
Please ensure you have added following to your Resource section before using it
<Window.Resources>
<ResourceDictionary>
<myNameSpace:ColorToSolidColorBrushValueConverter x:Key="colorToSolidColorBrushConverter"/>
</ResourceDictionary>
</Window.Resources>
Upvotes: 2