Change MVVM grid color on click

I really start in the MVVM pattern. I am trying to change the backgound of a grid by pressing a button. I have xaml with a grid containing a button, and ViewModel.cs, from where I want to change the background of the grid when the button is clicked. Until I just can show the MessageBox when I clicked ...

.xaml code:

<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> 

Code 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*/ } } } 

Sorry for my bad english.

Sincerely.

+5
source share
2 answers

By default, you must implement INotifyPropertyChanged in your ViewModel:

 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)); } } } 

Then add NotifyPropertyChanged () to your property installer.

Ok Then add a new property with the background color of the grid in the ViewModel:

 private Brush _gridBackground; public Brush GridBackground { get { return _gridBackground; } set { _gridBackground = value; NotifyPropertyChanged(); } } 

And bind the grid background to your property:

 <Grid Background="{Binding GridBackground}"> 

Finally, you can simply change the GridBackground in the command handler:

 public void ChangeBgColor(object obj) { GridBackground = Brushes.Blue; } 

You must remember that it is bad practice to add WPF classes, such as Brush, to your code. It is best to use IValueConverter in the XAML code and BCL classes in your ViewModel. For example, you can use the enumeration in the ViewModel and convert it to a brush in the ValueConverter.

  • Add a new enumeration for the ViewModel property:

     public enum GridState { Valid, Invalid } 
  • Change property type:

     private GridState _gridBackground; public GridState GridBackground { get { return _gridBackground; } set { _gridBackground = value; NotifyPropertyChanged(); } } 
  • Add new class with value converter

     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 } 
  • Add a new static resource to your control

      <UserControl.Resources> <converters:GridStateToBackgroundColorConverter x:Key="gridStateToBackgroundColorConverter" /> </UserControl.Resources> 
  • Update binding to your property

     <Grid Background="{Binding GridBackground, Converter={StaticResource gridStateToBackgroundColorConverter}"> 
+1
source

If you want to change the background color of the grid, you can use the command parameter. You can pass any user interface control as a parameter to the command. In your case, pass the grid to access the grid in your view model. Give a name to your grid and use that name to use as a command parameter. To do this, you need to implement the following code:

 <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> 

After making this change to the .xaml file. Deploy a parameterized relay command to use this passed grid for use in the Viewmodel file. To implement a parameterized relay command, try the following code:

  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. } 

I hope this works. Thanks.

-1
source

Source: https://habr.com/ru/post/1238506/


All Articles