MVVM在点击时改变网格的背景颜色

时间:2015-12-17 10:00:32

标签: c# wpf visual-studio xaml mvvm

我是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*/
        }
    }
}

抱歉我的英语不好。

最好的问候。

2 个答案:

答案 0 :(得分:1)

您应该在ViewModel中实现INotifyPropertyChanged

ko

然后,将NotifyPropertyChanged()添加到属性设置器。

确定。接下来,将带有网格背景颜色的新Property添加到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));
        }
    }
}

将你的网格背景绑定到你的财产:

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

最后,您只需在命令处理程序中更改GridBackground:

<Grid Background="{Binding GridBackground}">

你应该记住,在你的代码中添加像Brush这样的WPF类是不好的做法。更好的方法是在XAML代码中使用IValueConverter,在ViewModel中使用BCL类。例如,您可以在ViewModel中使用枚举,并将其转换为ValueConverter中的画笔。

  1. 为ViewModel的属性添加新枚举:

    public void ChangeBgColor(object obj)
    {
        GridBackground = Brushes.Blue;
    }
    
  2. 更改属性类型:

    public enum GridState { Valid, Invalid }
    
  3. 使用值转换器添加新类

    private GridState _gridBackground;
    public GridState GridBackground
    { 
        get { return _gridBackground; }
        set
        {
            _gridBackground = value;
            NotifyPropertyChanged();
        }
    }
    
  4. 向控件添加新的静态资源

    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
    }
    
  5. 更新与您的媒体资源的绑定

     <UserControl.Resources>
         <converters:GridStateToBackgroundColorConverter x:Key="gridStateToBackgroundColorConverter" />
     </UserControl.Resources>
    

答案 1 :(得分:-1)

如果要更改网格背景颜色,则可以使用命令参数。您可以将任何UI控件作为Command参数传递。在您的情况下,传递网格以访问视图模型中的网格。 将名称赋给网格并使用该名称作为命令参数。 为此,您需要实现如下代码:

<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文件进行此更改后。实现参数化中继命令以使用此传递的Grid在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.
    }

我希望这会奏效。谢谢。