2015-12-17 20 views
5

Sono un vero principiante nel modello MVVM. Sto provando a cambiare il backgound di una griglia sul clic del pulsante. Ho un xaml con una griglia contenente un pulsante e un ViewModel .cs da cui voglio cambiare lo sfondo della griglia sul clic del pulsante. Fino a quando non ho appena riesco a presentarsi un MessageBox quando ho cliccato ...MVVM modifica il colore di sfondo della griglia al clic

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

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

Scusate per il mio cattivo inglese.

Cordiali saluti.

risposta

1

fitst di tutto si dovrebbe implementare INotifyPropertyChanged nel vostro 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)); 
     } 
    } 
} 

Poi, aggiungere NotifyPropertyChanged() per la vostra proprietà setter.

Ok. Successivamente, aggiungere nuova proprietà con il colore di sfondo della griglia al vostro ViewModel:

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

e legare sfondo della griglia per il vostro bene:

<Grid Background="{Binding GridBackground}"> 

Infine si può semplicemente cambiare GridBackground nel gestore comando:

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

Si dovrebbe ricordare che è una cattiva pratica aggiungere classi WPF come Brush al codice. Il modo migliore è utilizzare IValueConverter in codice XAML e classi BCL nel ViewModel. Ad esempio, è possibile utilizzare l'enumerazione in ViewModel e convertirlo in pennello in ValueConverter.

  1. Aggiungi nuova enum per la vostra proprietà del ViewModel:

    public enum GridState { Valid, Invalid } 
    
  2. Cambio tipo di bene:

    private GridState _gridBackground; 
    public GridState GridBackground 
    { 
        get { return _gridBackground; } 
        set 
        { 
         _gridBackground = value; 
         NotifyPropertyChanged(); 
        } 
    } 
    
  3. Aggiungi nuova classe con convertitore di valore

    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. Aggiungi nuova risorsa statica per il vostro controllo

    <UserControl.Resources> 
        <converters:GridStateToBackgroundColorConverter x:Key="gridStateToBackgroundColorConverter" /> 
    </UserControl.Resources> 
    
  5. Aggiornamento vincolante per la vostra proprietà

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

SÌ! Grazie mille Vadim Martynov! Non sono sicuro di aver capito lo scopo di "INotifyPropertyChanged Interface" perché non mi ha notificato nulla ... ma la tua risposta è stata molto utile. Cordiali saluti. – Chefty

+0

@Chefty INPC è richiesto per il bindng dei dati. Senza di esso il tuo colore non cambierà quando cambierai proprietà in ViewModel. Inoltre, INPC è una caratteristica generale di associazione dei dati. Puoi leggere ulteriori informazioni su MSDN: https://msdn.microsoft.com/en-US/library/ms752347(v=vs.100).aspx –

+0

Non posso aggiungere nuove risorse statiche al mio controllo, si tratta di un errore: " GridStateToBackgroundColorConverter non è supportato in un progetto WPF "È normale? – Chefty

-1

Se si desidera cambiare il colore della griglia di sfondo, è possibile utilizzare il parametro di comando. Puoi passare qualsiasi controllo dell'interfaccia utente come parametro Comando. Nel tuo caso passa la griglia per accedere alla griglia nel tuo modello di vista. Assegna il nome alla tua griglia e usa quel nome da usare come parametro di comando. Per questo è necessario implementare il codice come questo:

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

Dopo questa modifica al file XAML. Implementare il comando di inoltro parametrico per utilizzare questa griglia passata da utilizzare nel file Viewmodel. Per implementare Comando Relay con parametri cercare di attuare seguente codice:

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

Spero che questo funzionerà. Grazie.

+0

Ciao! Grazie Dhruv Panchal, ma non è un lavoro. "RelayCommand " commette un errore e non riesco a risolverlo. – Chefty

+0

@Chefty Quale errore si sta ottenendo? Puoi dirmi? Hai implementato RelayCommand nella tua applicazione? –

+0

Mi è stato detto che RelayCommand non può essere utilizzato con argomenti di tipo. – Chefty

Problemi correlati