22.5 Kommandos
Viele Operationen brauchen Sie in fast jeder Anwendung: das Kopieren von Daten in die Zwischenablage, das Ausschneiden von markiertem Text, das Speichern von Änderungen usw. WPF vereinfacht die Codierungsarbeit dadurch, dass Ihnen eine große Zahl vorgefertigter Operationen zur Verfügung gestellt wird. Entwickeln Sie beispielsweise ein Menü mit dem Hauptmenüpunkt Bearbeiten und den untergeordneten Elementen Kopieren, Ausschneiden und Einfügen, brauchen Sie nur auf die vordefinierten Kommandos zurückzugreifen.
22.5.1 Vordefiniert
Die von WPF bereitgestellten Kommandos lassen sich in sechs Kategorien unterteilen. Jede Kategorie wird durch eine Klasse beschrieben:
- System.Windows.Annotations.AnnotationService
- System.Windows.Input.ApplicationCommands
- System.Windows.Input.ComponentCommands
- System.Windows.Documents.EditingCommands
- System.Windows.Input.MediaCommands
- System.Windows.Input.NavigationCommands
Jedes Kommando ist in einer klassengebundenen Eigenschaft vom Typ RoutedUICommand gespeichert. Um die Übersicht zu behalten, zeige ich in Tabelle 22.1 anhand einiger wichtiger Vertreter der Klasse ApplicationCommands den Umgang mit Kommandos.
Kategorie | Kommandos |
Dateien |
Close, New, Open, Save, SaveAs |
|
CancelPrint, Print, PrintPreview |
Bearbeiten |
Copy, CorrectionList, Cut, Delete, Paste, Redo, SelectAll, Undo |
Verschiedenes |
ContextMenu, Find, Help, NotACommand, Properties, Replace, Stop |
22.5.2 Beispielanwendung
Das folgende Beispiel zeigt ein Fenster mit zwei Textboxen und einem Menü mit den Punkten Datei und Bearbeiten:
'...\WPFKonzepte\Kommandos\Anwendung.xaml |
<Window ...> <DockPanel> <Menu DockPanel.Dock="Top" Name="mnuMenu"> <MenuItem Header="_Datei"> <MenuItem Command="ApplicationCommands.New" /> <MenuItem Command="ApplicationCommands.Open"> <MenuItem.Icon> <Image Source="Bilder/DateiÖffnen.png" /> </MenuItem.Icon> </MenuItem> <Separator /> <MenuItem Command="ApplicationCommands.Save"> <MenuItem.Icon> <Image Source="Bilder/DateiSpeichern.png" /> </MenuItem.Icon> </MenuItem> <MenuItem Command="ApplicationCommands.SaveAs" /> <Separator /> <MenuItem Header="_Senden an"> <MenuItem Header="_Mail" /> <MenuItem Header="_Desktop" /> </MenuItem> <MenuItem Header="_Beenden" /> </MenuItem> <MenuItem Header="_Bearbeiten"> <MenuItem Command="ApplicationCommands.Copy" /> <MenuItem Command="ApplicationCommands.Cut" /> <MenuItem Command="ApplicationCommands.Paste" /> </MenuItem> </Menu> <StackPanel> <TextBox Name="txtOben" Height="100"></TextBox> <TextBox Name="txtUnten" Height="100"></TextBox> </StackPanel> </DockPanel> </Window>
Die Menüpunkte werden automatisch beschriftet und haben die üblichen Shortcuts (siehe Abbildung 22.4).
Wenn Sie die Anwendung starten, funktioniert das gesamte Menü Bearbeiten bereits einwandfrei. Sie können Text markieren und kopieren oder ausschneiden und an anderer Stelle einfügen – in derselben Textbox oder von einer in die andere. Kann eine Operation nicht ausgeführt werden, zum Beispiel, weil sich keine Daten in der Zwischenablage befinden oder weil in der fokussierten TextBox keine Zeichen markiert sind, werden die entsprechenden Menüpunkte deaktiviert – all das, ohne eine Zeile Code zu schreiben.
Abbildung 22.4 Beispiel zu »ApplicationCommands«
22.5.3 Kommando-Ziel
Standardmäßig ist das Ziel eines Kommandos das in dem Moment aktive Steuerelement. Bei Bedarf können Sie aber auch ein anderes Ziel festlegen. Neben dem Command-Attribut muss dann auch noch das Attribut CommandTarget angegeben werden. Dabei muss wieder die Binding-Syntax verwendet werden, wie das folgende Beispiel zeigt:
... <MenuItem Header="_Bearbeiten"> <MenuItem Command="ApplicationCommands.Copy"/> <MenuItem Command="ApplicationCommands.Cut" /> <MenuItem Command="ApplicationCommands.Paste" CommandTarget="{Binding ElementName=txtUnten}" /> </MenuItem> ...
22.5.4 Kommandos an Ereignisse binden
Für die dateibezogenen Kommandos gibt es keine allgemeingültige Verhaltensweise. Daher sind sie standardmäßig mit keinem Code verbunden, und die Menüpunkte sind deaktiviert. Die Bindung eines Kommandos an einen Ereignishandler übernimmt ein Objekt vom Typ CommandBinding. Ein CommandBinding-Objekt muss mit seiner Eigenschaft Command an ein Kommando vom Typ Command gebunden werden. Üblicherweise werden diese Objekte im Element Window angegeben.
Das Ereignis Executed von CommandBinding wird zur Ausführung der gewünschten Operation ausgelöst, und mit CanExecute wird optional geprüft, ob der Befehl ausgeführt werden kann. Das Ergebnis der Prüfung speichern Sie innerhalb des Ereignishandlers in der Eigenschaft CanExecute des zweiten Parameters, der vom Typ CanExecuteRoutedEventArgs ist. Mit Can-Execute=False wird das Kommando deaktiviert.
Wir ergänzen die Anwendung so, dass das komplette Menü mit Kommandos verbunden ist. Dabei sollen die Menüpunkte Speichern und Speichern als nur dann aktiviert werden, wenn die obere der beiden Textboxen nicht leer ist.
'...\WPFKonzepte\Kommandos\Anwendung.xaml |
<Window ...> <Window.CommandBindings> <CommandBinding Command="ApplicationCommands.New" Executed="Neu" /> <CommandBinding Command="ApplicationCommands.Open" Executed="Öffnen" /> <CommandBinding Command="ApplicationCommands.Save" Executed="Speichern" CanExecute="KannSpeichern"/> <CommandBinding Command="ApplicationCommands.SaveAs" Executed="SpeichernAls" CanExecute="KannSpeichern" /> </Window.CommandBindings> <DockPanel> ... </Window>
In der Code-Behind-Datei sind die Operationen implementiert. Um das Beispiel einfach zu halten, werden die Aktionen durch Meldungsfenster simuliert.
Partial Public Class Anwendung Private Sub Neu(sender As Object, e As ExecutedRoutedEventArgs) MessageBox.Show("Menüpunkt 'Neu'") End Sub Private Sub Öffnen(sender As Object, e As ExecutedRoutedEventArgs) MessageBox.Show("Menüpunkt 'Öffnen'") End Sub Private Sub Speichern(sender As Object, e As ExecutedRoutedEventArgs) MessageBox.Show("Menüpunkt 'Speichern'") End Sub Private Sub SpeichernAls(sender As Object, e As ExecutedRoutedEventArgs) MessageBox.Show("Menüpunkt 'Speichern als'") End Sub Private Sub KannSpeichern(sender As Object, e As CanExecuteRoutedEventArgs) e.CanExecute = txtOben.Text <> "" End Sub End Class
22.5.5 Kommandos programmieren
Kommandos können Sie auch im Code erzeugen. Der entsprechende Ereignishandler wird mit der bekannten Notation an das Ereignis gebunden.
Private Sub Laden(sender As Object, e As RoutedEventArgs) _
Handles MyBase.Loaded
Dim cmdSave As New CommandBinding(ApplicationCommands.Save)
AddHandler cmdSave.Executed, AddressOf Speichern
End Sub
Sie können die Execute-Methode eines Kommandos auch aufrufen, um das Ereignis auszulösen. Der erste Parameter ist ein benutzerdefiniertes Objekt, der zweite die Angabe des Kommandoziels.
Private Sub button1_Click(sender As Object, e As RoutedEventArgs) ApplicationCommands.Save.Execute(Nothing, txtOben) End Sub
Hier ist das Kommandoziel eine Komponente namens txtOben.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.