2017-03-04 6 views
2

Den Pfad zu MVVM weitergehend, bin ich zu Tastenbefehlen gekommen. Nach einigem Hin und Her habe ich endlich ein funktionierendes Beispiel für einen Button_Click Befehl mit ICommand.Wie erkennt man, auf welche Schaltfläche geklickt wurde? (MVVM)

Mein Problem ist, dass ich jetzt ein generisches Ereignis gemacht habe, ich kann nicht bekommen, welcher Knopf geklickt wurde, um etwas Logik darauf anzuwenden. In meinem Beispiel habe ich nichts verwendet, wo ich die Sender Information bekommen konnte. Normalerweise so etwas wie dies unter Verwendung RoutedEventArgs:

Button button = (Button)sender; 

So ist das, was ich bis jetzt haben.

Die ICommand Klasse:

public class CommandHandler : ICommand 
{ 
    private Action _action; 
    private bool _canExecute; 
    public CommandHandler(Action action, bool canExecute) 
    { 
     _action = action; 
     _canExecute = canExecute; 
    } 

    public bool CanExecute(object parameter) 
    { 
     return _canExecute; 
    } 

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     _action(); 
    } 
} 

Und der Code die Aktion zu machen:

private ICommand _clickCommand; 
public ICommand ClickCommand => _clickCommand ?? (_clickCommand = new CommandHandler(MyAction, _canExecute)); 

public ViewModelBase() 
{ 
    _canExecute = true;    
} 

public void MyAction() 
{ 
    //Apply logic here to differentiate each button 
} 

Und das XAML,

<Button Command="{Binding ClickCommand}" Style="{StaticResource RedButtonStyle}">MyButton</Button> 

Wie würde ich mich über die Identifizierung, welche Taste ist wird geklickt, wenn derselbe Befehl an andere Schaltflächen gebunden wird?

+1

Nur neugierig, warum nicht nur * 2 * ICommands verwenden? –

+1

@XanderLuciano, ich dachte nur, einige Kriterien zu verwenden, die Tasten in der Methode zu unterscheiden war der Weg, es zu tun. Prost – KyloRen

+1

Fair genug! Ich habe gerade mit MVVM vor ungefähr einem Monat begonnen, also verstehe ich den Kampf damit, dein Denken anpassen zu müssen. Viel Glück! –

Antwort

1

Sie wahrscheinlich sollte nicht, aber wenn Sie wollen , können Sie CommandParameter=""

Sie sollte obwohl nur 2 ICommands verwenden.

XAML:

<Button Command="{Binding ClickCommandEvent}" CommandParameter="Jack"/>

Ansichtsmodell:

public RelayCommand ClickCommandEvent { get; set; } 

public SomeClass() 
{ 
    ClickCommandEvent = new RelayCommand(ClickExecute); 
} 

public void ClickExecute(object param) 
{ 
    System.Diagnostics.Debug.WriteLine($"Clicked: {param as string}"); 

    string name = param as string; 
    if (name == "Jack") 
     HighFive(); 
} 

und Ihre RelayCommand Klasse würde this boiler plate sein:

public class RelayCommand : ICommand 
{ 
    #region Fields 
    readonly Action<object> _execute; 
    readonly Predicate<object> _canExecute; 

    #endregion 

    #region Constructors 
    public RelayCommand(Action<object> execute) : this(execute, null) { } 

    public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
    { 
     if (execute == null) 
      throw new ArgumentNullException("execute"); 

     _execute = execute; 
     _canExecute = canExecute; 
    } 
    #endregion 

    #region ICommand Members 
    public bool CanExecute(object parameter) 
    { 
     return _canExecute == null ? true : _canExecute(parameter); 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    public void Execute(object parameter) 
    { 
     _execute(parameter); 
    } 
    #endregion 
} 
+1

Danke für die Antwort, für das Lernen Willen werde ich dies versuchen, aber ich werde mit separaten Befehlen im Projekt gehen. Prost – KyloRen

+1

Liebe die Begeisterung! Lass es mich wissen, wenn du Probleme hast! Sie werden MVVM lieben, wenn Sie sich erst einmal daran gewöhnt haben. Hast du schon 'INotifyPropertyChanged' gemacht? –

+1

Ich liebe dieses Zeug.Ja, ich habe 'INotifyPropertyChanged' implementiert, ich habe mit' DataGrid' und all seiner Idosyncrosis begonnen, kann aktualisieren, neue Datensätze hinzufügen usw., kann aber immer noch nicht herausfinden, wie man einen Datensatz mit 'Context.Menu' löscht. Also lasse ich das vorerst und starte auf Knopfbefehle. Derjenige, den ich am meisten fürchte, ist 'TreeView' und MVVM. – KyloRen

2

Sie sollten nicht alle Schaltflächen an denselben Befehl binden. Machen Sie einfach einen anderen Befehl für jede Schaltfläche.

+0

OK Ich sehe, also in dieser Hinsicht ist es ähnlich wie Ihre benannten Handler in nicht MVVM-Szenario, aber auf diese Weise ist der Code von der Ansicht entkoppelt. Danke – KyloRen

2

Dies wird Ihnen die angeklickt Button:

<Button Command="{Binding ClickCommand}" 
     CommandParameter="{Binding RelativeSource={RelativeSource Self}}"/> 
+0

UV für die Zeit nehmen, um mit einer hilfreichen Antwort zu helfen. Prost. – KyloRen

Verwandte Themen