C# 使用WPF和绑定单击时更改按钮背景色
我试图在单击时更改为按钮的颜色。它采用指定的初始颜色,但单击时不更新。我附加了我的代码,让我知道哪里出了问题。我试图实现下面文章中提供的代码 MainWindow.xaml代码段C# 使用WPF和绑定单击时更改按钮背景色,c#,wpf,mvvm,C#,Wpf,Mvvm,我试图在单击时更改为按钮的颜色。它采用指定的初始颜色,但单击时不更新。我附加了我的代码,让我知道哪里出了问题。我试图实现下面文章中提供的代码 MainWindow.xaml代码段 <Window.Resources> <viewModels:MainWindowViewModel x:Key="MainViewModel"/> </Window.Resources> <Border Padding="20"> <Stack
<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>
MainWindowViewModel.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;
}
}
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));
}
}
}
}
最后
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();
}
}
}
您需要在BackgroundColorBtn1属性上调用OnPropertyChanged,因为您正在更改私有备份变量,并且需要通知视图 您可以按如下方式修改MyAction方法
public void MyAction()
{
_backgroundColorBtn1 = Colors.Blue;
OnPropertyChanged(nameof(BackgroundColorBtn1));
}
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();
}
}
或者,您可以直接设置属性而不是backing字段,后者将调用OnPropertyChanged调用本身
public void MyAction()
{
BackgroundColorBtn1 = Colors.Blue;
}
您还需要使用颜色到笔刷转换器。按钮的背景属性接受笔刷,而不是颜色。转换器将允许您将所选颜色转换为笔刷
您可以如下定义转换器
public void MyAction()
{
_backgroundColorBtn1 = Colors.Blue;
OnPropertyChanged(nameof(BackgroundColorBtn1));
}
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();
}
}
然后,你可以把它当作
Background="{Binding BackgroundColorBtn1, Converter={StaticResource colorToSolidColorBrushConverter}}"
请确保在使用资源部分之前已将以下内容添加到资源部分
<Window.Resources>
<ResourceDictionary>
<myNameSpace:ColorToSolidColorBrushValueConverter x:Key="colorToSolidColorBrushConverter"/>
</ResourceDictionary>
</Window.Resources>
设置属性而不是备份字段可能更好。属性的setter已经具备了引发属性更改通知的所有必要逻辑…@elgonzo yes。我会在回答时提到同样的问题。自从他使用了Private field后,他已经回答了有关它的问题,并想指出问题的原因。谢谢@Anu Viswan,我尝试了两种方法,但单击后仍然没有变为蓝色。@ManojPathak我已经更新了我的答案,请您检查一下,您也缺少了一个颜色到笔刷的转换器