Verfasst von: bletra | 9. Mai 2011

WPF: Von Spaghetticode zu MVVM – Teil 5 von 9

In dieser Artikelserie möchte ich eine einfache Applikation, in eine testbare Applikation nach dem MVVM-Pattern umwandeln:

  1. Beispielapplikation mit Spaghetticode
  2. Refactoring 1: Model
  3. MVC, MVP, Presentation Model
  4. MVVM
  5. ICommand
  6. Binding
  7. Refactoring 2: ViewModel
  8. Refactoring 3: View
  9. Zusammenfassung

Commands

Es gibt eine Reihe von vordefinierten Commands in .Net:

Diese können einfach an ein Ereignis der GUI gebunden werden:

<MenuItem Command ="ApplicationCommands.Copy"/>

Hiermit lässt sich so ohne jegliche C#-Programmierung ein einfacher Editor implementieren (siehe WPF – A simple text Editor in less than 20 lines of markup!)

Die Basis dieser Commands sind ICommand und RoutedCommand, die von ICommand erbt. ICommand ist eine Schnittstelle des Namensraums System.Windows.Input und ist wie folgt definiert:

public interface ICommand
{
  bool CanExecute(Object parameter);
  void Execute(Object parameter);
  event EventHandler CanExecuteChanged;
}

Über CanExecute wird ein disable/enable des Commands und damit des diesen Commands nutzenden GUI-Elements (z.B. Button) definiert.

Man kann nun für jeden Command, den das ViewModel zur Verfügung stellt, eine eigene Klasse programmieren, die ICommand implementiert. Häufig kommt jedoch ein generischer Ansatz auf Basis von Delegates (Generische Delegates) zum Einsatz. In Anlehnung an die Artikel „ICommand is like a chocolate cake“  und „WPF-Anwendungen mit dem Model-View-ViewModel-Entwurfsmuster“ verwende ich folgende Basisklasse für Commands:

public class DelegateCommand : ICommand
{
  private readonly Action<object> _executeDelegate;
  private readonly Func<object, bool> _canExecuteDelegate;
  public DelegateCommand(Action<object> executeDelegate)
    : this(executeDelegate, null)  { }

  public DelegateCommand(Action<object> executeDelegate, Func<object, bool> canExecuteDelegate)
  {
    _executeDelegate = executeDelegate;
    _canExecuteDelegate = canExecuteDelegate;
  }
  public void Execute(object parameter)
  {
    _executeDelegate(parameter);
  }

  public bool CanExecute(object parameter)
  {
    return _canExecuteDelegate == null ? true : _canExecuteDelegate(parameter);
  }
  public event EventHandler CanExecuteChanged //see http://msdn.microsoft.com/de-de/magazine/dd419663.aspx#id0090030
  {
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
  }
}

Durch die Weiterleitung von CanExecuteChanged an CommandManager.RequerySuggested wird sichergestellt, dass die WPF-Befehlsinfrastruktur jedes Mal, wenn sie die integrierten Befehle befragt, alle DelegateCommand-Objekte fragt, ob sie ausgeführt werden können.

Zu Beginn des Artikels wurde gezeigt, wie vordefinierte Commands in XAML genutzt werden können. Im nächsten Artikel schreibe ich über „Binding“ in Bezug auf Commands und in Bezug auf Daten.

Advertisements

Responses

  1. […] verwende ich die in Artikel „WPF: Von Spaghetticode zu MVVM – Teil 5 von 9″ eingeführte Klasse […]


Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

Kategorien

%d Bloggern gefällt das: