Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 6. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Das Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Strukturen und Enumerationen
7 Fehlerbehandlung und Debugging
8 Auflistungsklassen (Collections)
9 Generics – Generische Datentypen
10 Weitere C#-Sprachfeatures
11 LINQ
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 XML
15 Multithreading und die Task Parallel Library (TPL)
16 Einige wichtige .NET-Klassen
17 Projektmanagement und Visual Studio 2012
18 Einführung in die WPF und XAML
19 WPF-Layout-Container
20 Fenster in der WPF
21 WPF-Steuerelemente
22 Elementbindungen
23 Konzepte von WPF
24 Datenbindung
25 Weitere Möglichkeiten der Datenbindung
26 Dependency Properties
27 Ereignisse in der WPF
28 WPF-Commands
29 Benutzerdefinierte Controls
30 2D-Grafik
31 ADO.NET – Verbindungsorientierte Objekte
32 ADO.NET – Das Command-Objekt
33 ADO.NET – Der SqlDataAdapter
34 ADO.NET – Daten im lokalen Speicher
35 ADO.NET – Aktualisieren der Datenbank
36 Stark typisierte DataSets
37 Einführung in das ADO.NET Entity Framework
38 Datenabfragen des Entity Data Models (EDM)
39 Entitätsaktualisierung und Zustandsverwaltung
40 Konflikte behandeln
41 Plain Old CLR Objects (POCOs)
Stichwort

Download:
- Beispiele, ca. 62,4 MB

Buch bestellen
Ihre Meinung?

Spacer
Visual C# 2012 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2012

Visual C# 2012
Rheinwerk Computing
1402 S., 6., aktualisierte und erweiterte Auflage 2013, geb., mit DVD
49,90 Euro, ISBN 978-3-8362-1997-6
Pfeil 28 WPF-Commands
Pfeil 28.1 Allgemeine Beschreibung
Pfeil 28.1.1 Ein einführendes Beispiel
Pfeil 28.2 Vordefinierte WPF-Commands
Pfeil 28.3 Commands verwenden
Pfeil 28.3.1 Command-Bindungen einrichten
Pfeil 28.3.2 Lokalität der Befehlsbindung
Pfeil 28.3.3 Befehlsbindung mit Programmcode
Pfeil 28.3.4 Das Befehlsziel mit »CommandTarget« angeben
Pfeil 28.3.5 Zusätzliche Daten bereitstellen
Pfeil 28.3.6 Befehle mit Maus oder Tastatur aufrufen
Pfeil 28.4 Die Anatomie eines »Command«-Objekts
Pfeil 28.4.1 Das Interface »ICommand«
Pfeil 28.4.2 Die Klassen »RoutedCommand« und »RoutedUICommand«
Pfeil 28.4.3 Das Interface »ICommandSource«
Pfeil 28.5 Das MVVM-Pattern
Pfeil 28.5.1 Ein simples Beispielprogramm

Galileo Computing - Zum Seitenanfang

28.3 Commands verwendenZur nächsten Überschrift

Nicht alle Steuerelemente können vordefinierte WPF-Commands registrieren. Diese Fähigkeit bleibt den Controls vorbehalten, die das Interface ICommandSource implementieren. Dazu gehören beispielsweise ButtonBase, HyperLink und MenuItem sowie deren Ableitungen. Die Schnittstelle stellt dazu die Eigenschaft Command zur Verfügung, bei der ein WPF-Command registriert wird, wie oben im XAML-Code zu sehen ist.

Hinter einem WPF-Command steckt natürlich auch Programmlogik. Textboxen sind bereits so ausgestattet, dass sie mit den WPF-Befehlen Copy, Cut, Paste, aber auch Redo und Undo umgehen können. Klickt der Anwender auf eine Schaltfläche oder ein Menüelement, wird der Befehl automatisch ausgeführt und von der TextBox behandelt, die in diesem Moment den Fokus hat. Bei diesen Operationen handelt es sich um Standardoperationen, die auf dem fokussierten Steuerelement ausgeführt werden. Befehle wie beispielsweise Open oder New kennen solche allgemeingültigen Operationen nicht. Daher bieten diese Kommandos keine Programmlogik, Sie müssen diese selbst schreiben. Dazu sind Befehlsbindungen notwendig, die wir uns nun ansehen wollen.

Sollten Sie das Beispiel »Sample1« mit Schaltflächen ausprobieren, die sich nicht in einer Menüleiste oder der Symbolleiste befinden, wird das Verhalten zur Laufzeit nicht wie gewünscht sein. Tatsächlich tragen die Elemente Menu und ToolBar dazu bei, die aktuell fokussierte TextBox zu lokalisieren. Im weiteren Verlauf dieses Kapitels kommen wir auf diese Situation noch einmal zu sprechen.


Galileo Computing - Zum Seitenanfang

28.3.1 Command-Bindungen einrichtenZur nächsten ÜberschriftZur vorigen Überschrift

Schauen wir uns noch einmal die Registrierung eines Commands bei einem command-fähigen Steuerelement an:

<Button Command="ApplicationCommands.Help" Content="Hilfe" />

Listing 28.2 Registrierung eines Commands

Im Button wird mit der Eigenschaft Command der Help-Befehl mit der Schaltfläche verbunden. Wie oben gezeigt, kann die Eigenschaft auch in der Kurzform

<Button Command="Help" Content="Hilfe" />

Listing 28.3 Kurzform der Command-Registrierung

ausgedrückt werden.

Der Anwender wird bis zu diesem Zeitpunkt die Schaltfläche nicht nutzen können, denn sie ist deaktiviert. Das ist das Standardverhalten und hat seine Ursache darin, dass mit dem Befehl Help keine Logik verknüpft ist.

Zur Ausführung der Befehlslogik beim Aufruf eines Commands werden Ereignisse ausgelöst, deren Ereignishandler registriert werden müssen. In den Ereignishandlern wird das Verhalten des betreffenden Befehls beschrieben.

Der nächste Schritt besteht also darin, einen Ereignishandler bereitzustellen, der auf den Befehl ApplicationCommands.Help reagiert. Dazu ist eine Instanz der Klasse CommandBinding erforderlich, die den Befehl mit dem Ereignishandler verknüpft. Da innerhalb einer Komponente auch mehrere Commands ausgelöst werden können, werden alle Commands in einer Collection zusammengefasst, die durch die Eigenschaft CommandBindings beschrieben wird. Meistens wird die Liste der Bindungen mit dem Window verknüpft.

<Window.CommandBindings>
<CommandBinding Command="Help"
CanExecute="Help_CanExecute"
Executed="Help_Executed" />
</Window.CommandBindings>
<Button Command="Help" />

Listing 28.4 Definieren einer Kommandobindung samt ihren Ereignishandlern

Executed und CanExecute sind zwei Events des CommandBinding-Objekts. Dabei wird Executed ausgelöst, wenn der Anwender auf das auslösende Element klickt, zum Beispiel auf eine Schaltfläche. Somit verbirgt sich hinter diesem Ereignis die Logik, die der Befehl beschreiben soll.

private void Help_Executed(object sender, ExecutedRoutedEventArgs e) {
MessageBox.Show("Logik des Help-Commands.");
}

Listing 28.5 Ereignishandler des Events »Executed«

Das zweite Ereignis CanExecute wird ausgelöst, wenn der Befehl seinerseits prüft, ob er für das Befehlsziel ausgeführt werden kann.

private void Help_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = true;
}

Listing 28.6 Ereignishandler des Events »CanExecute«

Um den Button zu aktivieren, muss im Ereignishandler des CanExecute die Eigenschaft CanExecute des CanExecuteEventArgs-Parameters auf true gesetzt werden. false ist die Vorgabe und demnach die Ursache dafür, dass der Button zu Beginn dieses Abschnitts zunächst deaktiviert war. In diesem Ereignishandler erfolgt in der Regel die Überprüfung einer Bedingung, um festzustellen, ob die mit dem Befehl verknüpften Controls aktiviert oder deaktiviert dargestellt werden sollen. Für unser Codefragment ist vollkommen ausreichend, die Schaltfläche dauerhaft zu aktivieren.

Die Kurzform der Command-Registrierung kann nur im Zusammenhang mit vordefinierten Befehlen benutzt werden. Bei benutzerdefinierten Kommandos müssen Sie die folgende Syntaxschreibweise verwenden:

<Button Command="{x:Static UserdefinedCommands.DoIt}" Content="Mach es" />

Galileo Computing - Zum Seitenanfang

28.3.2 Lokalität der BefehlsbindungZur nächsten ÜberschriftZur vorigen Überschrift

Die Bindung des Befehls erfolgte im Beispiel des letzten Abschnitts für das Window innerhalb der Eigenschaft CommandBindings. Diese Eigenschaft besitzen alle Elemente, die entweder von UIElement, UIElement3D oder ContentElement abgeleitet sind. Dazu gehört auch die Klasse Button. Folglich kann die Befehlsbindung auch in der Schaltfläche selbst erfolgen:

<Button Command="ApplicationCommands.Help">
<Button.CommandBindings>
<CommandBinding Command="Help"
CanExecute="Help_CanExecute"
Executed="Help_Executed" />
<Button.CommandBindings>
</Button>

Listing 28.7 Befehlsbindung innerhalb eines WPF-Elements

Andere Elemente, die sich ebenfalls mit dem Help-Befehl verknüpfen, können diese Befehlsbindung nicht nutzen – sie ist exklusiv für die Schaltfläche. Da die Bindungsangabe im Window für alle Elemente des Fensters, die den Befehl nutzen, gleichermaßen gilt, kann mit einer lokalen Kommandobindung in einem Steuerelement ein objektspezifisches Befehlsverhalten realisiert werden. Dabei wird auch gegebenenfalls eine ebenfalls vorhandene Befehlsbindung im Window für das entsprechende Element außer Kraft gesetzt. Genauso arbeitet übrigens die TextBox im Zusammenhang mit Befehlen, die auf die Zwischenablage zugreifen (Copy, Cut und Paste).

Leider ist es nicht möglich, Befehlsbindungen in der Datei App.xaml abzulegen, da die Klasse Application Befehlsbindungen nicht unterstützt. Somit bleibt Ihnen nichts anderes übrig, als alle notwendigen Befehlsbindungen in jedem Fenster ausdrücklich anzugeben.


Galileo Computing - Zum Seitenanfang

28.3.3 Befehlsbindung mit ProgrammcodeZur nächsten ÜberschriftZur vorigen Überschrift

Im folgenden Codefragment wird gezeigt, wie man die Befehlsbindung auch mit Code erstellen kann. Es ist sinnvoll, den Code im Konstruktor des Window hinter der Methode InitializeComponent anzugeben.

public MainWindow() {
InitializeComponent();
CommandBinding binding = new CommandBinding(ApplicationCommands.Help);
this.CommandBindings.Add(binding);
binding.Executed += Help_Executed;
binding.CanExecute += Help_CanExecute;
}

Listing 28.8 Befehlsbindung mit C#-Programmcode


Galileo Computing - Zum Seitenanfang

28.3.4 Das Befehlsziel mit »CommandTarget« angebenZur nächsten ÜberschriftZur vorigen Überschrift

Wird ein Kommando abgesetzt, ist per Vorgabe das Element, das den Fokus hat, Ziel des Befehls. Mit der Eigenschaft CommandTarget können Sie auch ein anderes Ziel festlegen. Dabei handelt es sich um die Komponente, für die die Ereignisse Executed und CanExecute ausgelöst werden sollen.

Im Einführungsbeispiel Sample1 dieses Kapitels haben Sie gesehen, dass eine »Magie« dafür sorgt, dass die Befehle Copy und Paste (und natürlich auch Cut) auf dem richtigen Zielelement ausgeführt werden – nämlich der fokussierten TextBox. Im Hintergrund spielt sich dabei ein Prozess ab, der das fokussierte Steuerelement ermittelt. Dieser Prozess wird entweder von den Elementen Menu oder ToolBar gesteuert.

Das Verhalten ändert sich sofort, wenn sich die Schaltfläche, die den abonnierten Command auslöst, nicht innerhalb eines Menu-Elements oder einer ToolBar befindet. In diesem Fall muss das Ziel des Kommandos manuell angegeben werden. Dazu wird die Eigenschaft CommandTarget benutzt. Im Beispiel Sample2 wird das gezeigt.

Abbildung

Abbildung 28.2 Fenster des Beispiels »Sample2«

// Beispiel: ..\Kapitel 28\RoutedCommands\Sample2

<Window ...
Title="Sample2" Width="300" Height="135">
<StackPanel>
<WrapPanel>
<Button Width="130" Height="30" Command="ApplicationCommands.Copy"
CommandTarget="{Binding ElementName=text1}">Kopieren
</Button>
<Button Width="130" Height="30" Command="ApplicationCommands.Paste"
CommandTarget="{Binding ElementName=text1}">Einfügen
</Button>
</WrapPanel>
<TextBox Name="text1" Margin="5" Height="25" Background="AntiqueWhite"
FontSize="14"></TextBox>
<TextBox Name="text2" Margin="5,0,5,5" Height="25"
Background="AntiqueWhite" FontSize="14"></TextBox>
</StackPanel>
</Window>

Listing 28.9 Angabe des Ziels eines »Command«-Aufrufs

Beachten Sie, dass der Eigenschaft CommandTarget ein Binding-Objekt übergeben wird. Mit ElementName wird das Befehlsziel angegeben.

Das Festlegen des Befehlsziels mit CommandTarget hat den Nachteil, dass nur ein bestimmtes Element als Ziel angegeben werden kann. Im Beispielprogramm ist es die TextBox mit dem Bezeichner text1. Besser ist eine Lösung, bei der ein Findungsmechanismus die aktuell fokussierte TextBox ermittelt. Dazu wird für die beiden Schaltflächen aus Sample3 ein eigener Fokusbereich definiert. Die beiden Textboxen dürfen diesem Bereich nicht angehören. Die Folge ist, dass beim Klicken auf eine der Schaltflächen die entsprechende TextBox weiterhin den Fokus behält und dieser nicht an die angeklickte Schaltfläche weitergereicht wird.

Ein Fokusbereich wird festgelegt, indem man in einem Containerelement

FocusManager.IsFocusScope=True

setzt. Das Containerelement beschreibt damit den Fokusbereich.

// Beispiel: ..\Kapitel 28\RoutedCommands\Sample3

<StackPanel>
<WrapPanel FocusManager.IsFocusScope="True">
<Button Width="130" Height="30" Command="ApplicationCommands.Copy">
Kopieren
</Button>
<Button Width="130" Height="30" Command="ApplicationCommands.Paste">
Einfügen
</Button>
</WrapPanel>
<TextBox Name="text1" Margin="5" Height="25" Background="AntiqueWhite"
FontSize="14"></TextBox>
<TextBox Name="text2" Margin="5,0,5,5" Height="25" Background="AntiqueWhite"
FontSize="14"></TextBox>
</StackPanel>

Listing 28.10 Dem fokusbesitzenden Element das Kommando zuteilen


Galileo Computing - Zum Seitenanfang

28.3.5 Zusätzliche Daten bereitstellenZur nächsten ÜberschriftZur vorigen Überschrift

Steuerelemente, die ein WPF-Kommando abonnieren, implementieren die Schnittstelle ICommandSource. Das Interface schreibt neben der Eigenschaft Command und CommandTarget auch die Eigenschaft CommandParameter vor. CommandParameter dient dazu, dem Kommando zusätzliche Daten zu übermitteln. Die Eigenschaft ist vom Typ Object.

<Window.CommandBindings>
<CommandBinding Executed="Help_Executed"
CanExecute="Help_CanExecute"/>
</Window.CommandBindings>
<Button Command="ApplicationCommands.Help"
CommandParameter="Guten Morgen liebe Sorgen .." Content="Help">
</Button>

Listing 28.11 Kommandoparameter übergeben

Entgegengenommen wird das Objekt im EventArgs-Parameter des Executed-Ereignishandlers. Hier liefert die Eigenschaft Parameter das übermittelte Objekt ab und kann innerhalb der Methode benutzt werden. Im folgenden Listing wird die Zeichenfolge ganz einfach nur in einem Hinweisfenster angezeigt:

private void Help_Executed(object sender, ExecutedRoutedEventArgs e) {
MessageBox.Show(e.Parameter.ToString());
}

Listing 28.12 Auswerten der Übergabeparameter


Galileo Computing - Zum Seitenanfang

28.3.6 Befehle mit Maus oder Tastatur aufrufenZur vorigen Überschrift

In Windows-Anwendungen sind häufig bestimmte Befehle mit Tastenkombinationen ausführbar. Denken Sie beispielsweise an die Taste Esc, um eine laufende Aktion abzubrechen oder ein Fenster zu schließen. Das WPF-Befehlsmodell gestattet es Ihnen, einen WPF-Command entweder mit einer Taste bzw. Tastenkombination auszuführen oder bei Betätigung der Maus.

Zu diesem Zweck dienen die Klassen KeyBinding und MouseBinding. Um zum Beispiel die Tastenkombination Alt + F10 mit dem Befehl Help zu verbinden, genügt der folgende XAML-Code:

<KeyBinding Key="F10" Modifiers="Alt" Command="Help" />

Listing 28.13 Tastenkombination mit einem »Command« verknüpfen

Der Eigenschaft Key wird ein Member der gleichnamigen Enumeration übergeben, Modifiers gibt die Modifizierertaste an, die der Enumeration ModifierKeys entstammt.

Sehr ähnlich können Sie Mausaktionen mit einem Befehl verbinden.

<MouseBinding Gesture="Alt+RightClick" Command="Open" />

Listing 28.14 Maus an ein »Command« binden

In diesem Fall wird der Open-Befehl ausgeführt, wenn beim Klicken auf die rechte Maustaste die Alt-Taste gedrückt ist. In der MouseAction-Enumeration sind die möglichen Mausaktionen beschrieben, die sich wieder mit einer Modifizierertaste kombinieren lassen und der Eigenschaft Gesture übergeben werden.

Alle Maus- und Tastaturzuordnungen werden in einer InputBindingsCollection zusammengefasst, die über die Eigenschaft InputBindings veröffentlicht wird. Es bietet sich an, die Collection dem Window zuzuordnen.

Im folgenden Beispielprogramm sind im Fenster nur zwei Schaltflächen enthalten, die die Befehle Help und Open abonnieren. Jedem der beiden Befehle ist eine Tastatur- und Mausaktion zugeordnet.

// Beispiel: ..\Kapitel 28\RoutedCommands\Sample4

<Window ... >
<Window.CommandBindings>
<CommandBinding Command="Help" CanExecute="Help_CanExecute"
Executed="Help_Executed" />
<CommandBinding Command="Open" CanExecute="Open_CanExecute"
Executed="Open_Executed" />
</Window.CommandBindings>

<Window.InputBindings>

<KeyBinding Key="F10" Modifiers="Alt" Command="Help" />

<MouseBinding Gesture="Alt+WheelClick" Command="Help" />

<KeyBinding Key="F11" Modifiers="Control" Command="Open" />

<MouseBinding Gesture="Alt+RightClick" Command="Open" />

</Window.InputBindings>

<StackPanel>

<Button Height="45" Content="Help" Command="Help" />

<Button Height="45" Content="Open" Command="Open" />

</StackPanel>

</Window>

Listing 28.15 Das Beispielprogramm »Sample 4«

Zu diesem Beispiel gehört der folgende XAML-Code:

private void Help_Executed(object sender, ExecutedRoutedEventArgs e) {
MessageBox.Show("Logik des Help-Commands.");
}

private void Help_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = true;
}

private void Open_Executed(object sender, ExecutedRoutedEventArgs e) {
MessageBox.Show("Logik des Open-Commands.");

}

private void Open_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = true;
}

Listing 28.16 Der Ablauf beim Aufruf eines Commands



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2012

Visual C# 2012
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: C/C++






 C/C++


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2013
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de