MVVM 在单击时更改网格的背景颜色
Posted
技术标签:
【中文标题】MVVM 在单击时更改网格的背景颜色【英文标题】:MVVM changing grid's background color on click 【发布时间】:2016-03-23 17:57:23 【问题描述】:我是 MVVM 模式的真正初学者。我正在尝试在单击按钮时更改网格的背景。我有一个带有包含按钮的网格的 xaml 和一个 ViewModel .cs,我想在单击按钮时更改网格的背景。直到我点击时成功显示了一个 MessageBox...
.xaml 代码:
<Window x:Class="WpfSimple.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfSimple"
Title="MainWindow" Height="150" Width="370">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Button Content="Click"
Height="23"
HorizontalAlignment="Left"
Background="Gray"
Margin="75.944,47.465,0,0"
Name="btnClick"
VerticalAlignment="Top"
Width="203"
Command="Binding ButtonCommand"/>
<!--What is necessary to add for changing grid color ? Commandparameter ?-->
</Grid>
MainWindowViewModel.cs 代码:
namespace WpfSimple
class MainWindowViewModel
private ICommand m_ButtonCommand;
public ICommand ButtonCommand
get
return m_ButtonCommand;
set
m_ButtonCommand = value;
public MainWindowViewModel()
ButtonCommand=new RelayCommand(new Action<object>(ChangeBgColor));
public void ChangeBgColor(object obj)
/*HERE I WANT TO CHANGE GRID COLOR*/
对不起,我的英语不好。
最好的问候。
【问题讨论】:
【参考方案1】:您最应该在 ViewModel 中实现 INotifyPropertyChanged:
public class MainWindowViewModel : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
然后,将 NotifyPropertyChanged() 添加到您的属性设置器。
好的。接下来,将带有网格背景颜色的新属性添加到 ViewModel:
private Brush _gridBackground;
public Brush GridBackground
get return _gridBackground;
set
_gridBackground = value;
NotifyPropertyChanged();
并将您的网格背景绑定到您的属性:
<Grid Background="Binding GridBackground">
最后,您可以在命令处理程序中更改 GridBackground:
public void ChangeBgColor(object obj)
GridBackground = Brushes.Blue;
您应该记住,将诸如 Brush 之类的 WPF 类添加到您的代码中是一种不好的做法。更好的方法是在您的 ViewModel 中的 XAML 代码和 BCL 类中使用 IValueConverter。例如,可以在 ViewModel 中使用枚举,在 ValueConverter 中将其转换为画笔。
为 ViewModel 的属性添加新枚举:
public enum GridState Valid, Invalid
更改属性类型:
private GridState _gridBackground;
public GridState GridBackground
get return _gridBackground;
set
_gridBackground = value;
NotifyPropertyChanged();
使用值转换器添加新类
public class GridStateToBackgroundColorConverter : IValueConverter
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
GridState val = (GridState) value;
if(val == GridState.Valid)
return Brushes.Green;
return Brushes.Red;
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
throw new NotSupportedException();
#endregion
向您的控件添加新的静态资源
<UserControl.Resources>
<converters:GridStateToBackgroundColorConverter x:Key="gridStateToBackgroundColorConverter" />
</UserControl.Resources>
更新绑定到您的属性
<Grid Background="Binding GridBackground, Converter=StaticResource gridStateToBackgroundColorConverter">
【讨论】:
是的!非常感谢瓦迪姆·马丁诺夫!我不确定我是否理解“INotifyPropertyChanged Interface”的目的,因为它根本没有通知我......但你的回答真的很有帮助。最好的问候。 @Chefty INPC 是数据绑定所必需的。没有它,当您更改 ViewModel 中的属性时,您的颜色不会改变。此外,INPC 是数据绑定的一般特征。您可以在 MSDN 上阅读更多内容:msdn.microsoft.com/en-US/library/ms752347(v=vs.100).aspx 我无法向控件添加新的静态资源,报错:“WPF项目不支持GridStateToBackgroundColorConverter”正常吗? 完全没有。而且很难理解这个问题。 1.您的转换器是否真正实现了 System.Windows.Data 中的 IValueConverter? 2.你的converter类和view在同一个项目吗?我在这里找到了一条指令:***.com/questions/28607372/… 我认为您应该像在那个答案中一样添加转换器命名空间:xmlns:converters="clr-namespace:YourAppName.YourNamespaceWithConverter" 是的 IValueConverter 是从 System.Windows.Data 实现的,现在我无法使转换器命名空间工作。我的应用程序名称是“WpfSimple”,包含 Converter 类的命名空间也被命名为“WpfSimple”......我将您的类“GridStateToBackgroundColorConverter”复制到第一个类“MainWindowViewModel”中,因为它是我声明“GridState”变量的地方。这是个坏主意吗?【参考方案2】:如果你想改变网格背景颜色,那么你可以使用命令参数。您可以将任何 UI 控件作为命令参数传递。在您的情况下,通过网格访问视图模型中的网格。 为您的网格命名并使用该名称作为命令参数。 为此,您需要实现如下代码:
<Window x:Class="WpfSimple.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfSimple"
Title="MainWindow" Height="150" Width="370">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid Name="grid">
<Button Content="Click"
Height="23"
HorizontalAlignment="Left"
Background="Gray"
Margin="75.944,47.465,0,0"
Name="btnClick"
VerticalAlignment="Top"
Width="203"
Command="Binding ButtonCommand"
CommandParameter="Binding Elementname="grid""/>
</Grid>
对 .xaml 文件进行此更改后。实施参数化中继命令以使用此传递的网格在您的 Viewmodel 文件中使用。 实现参数化中继命令尝试实现以下代码:
private ICommand m_ButtonCommand;
public ICommand ButtonCommand
get
return m_ButtonCommand;
set
m_ButtonCommand = value;
public MainWindowViewModel()
ButtonCommand=new RelayCommand<Grid>(ChangeBgColor);
public void ChangeBgColor(Grid grid)
if(grid!=null)
grid.Background = Brushes.Red; //Any color you want to change.
我希望这会奏效。谢谢。
【讨论】:
嗨!谢谢 Dhruv Panchal,但它不起作用。 “RelayCommand以上是关于MVVM 在单击时更改网格的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章