Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM changing grid's background color on click

I'm a true beginner in MVVM pattern. I'm trying to change the backgound of a grid on button's click. I have a xaml with a grid containing a button, and a ViewModel .cs from where i want to change the grid's background on button's click. Until there i just succeed to show up a 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>

MainWindowViewModel.cs code:

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.

Best regards.

like image 788
Chefty Avatar asked Nov 08 '22 23:11

Chefty


1 Answers

Fitst of all you should 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 properties setter.

Ok. Next, add new Property with your grid background color to your ViewModel:

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

And bind your grid's background to your property:

<Grid Background="{Binding GridBackground}">

Finally you can just change GridBackground in the command handler:

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

You should remember that it's a bad practice to add WPF-classes like Brush to your code. The better way is to use IValueConverter in XAML code and BCL classes in your ViewModel. For example, you can use enumeration in ViewModel and convert it to brush in ValueConverter.

  1. Add new enum for your ViewModel's property:

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

    private GridState _gridBackground;
    public GridState GridBackground
    { 
        get { return _gridBackground; }
        set
        {
            _gridBackground = value;
            NotifyPropertyChanged();
        }
    }
    
  3. 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
    }
    
  4. Add new static resource to your control

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

    <Grid Background="{Binding GridBackground, Converter={StaticResource gridStateToBackgroundColorConverter}">
    
like image 72
Vadim Martynov Avatar answered Nov 15 '22 07:11

Vadim Martynov