Übersicht über die Eingabe

Das Windows Presentation Foundation (WPF)-Subsystem bietet eine leistungsstarke API zum Abrufen von Eingabe von einer Vielzahl von Geräten, einschließlich Maus, Tastatur, Touchpad und Stift. In diesem Thema werden die Dienste beschrieben, die von WPF bereitgestellt werden sowie die Architektur des Eingabesystems.

Eingabe-API

Die primären Funktionen der Eingabe-API finden sich in den Basiselementklassen: UIElement, ContentElement, FrameworkElement und FrameworkContentElement. Weitere Informationen zu den Basiselementen finden Sie unter Übersicht über Basiselemente. Diese Klassen bieten Funktionen für Eingabeereignisse, die im Zusammenhang mit Tastatureingaben, Maustasten, dem Mausrad, der Bewegung der Maus, der Fokusverwaltung und Mauseingabe stehen, um nur einige zu nennen. Anstatt alle Eingabeereignisse als einen Dienst zu behandeln, ermöglicht die Eingabearchitektur durch die Platzierung der Eingabe-API auf Basiselementen, dass die Eingabeereignisse von einem bestimmten Objekt auf der Benutzeroberfläche stammen und ein Ereignisroutingschema unterstützen, wobei mehr als ein Element die Möglichkeit hat, ein Eingabeereignis zu behandeln. Vielen Eingabeereignissen ist ein Paar von Ereignissen zugeordnet. So ist beispielsweise das Ereignis für eine gedrückte Taste mit den Ereignissen KeyDown und PreviewKeyDown verbunden. Der Unterschied zwischen diesen Ereignissen ist, wie an das Zielelement weitergeleitet werden. Vorschauereignisse tunneln die Elementstruktur vom Stammelement hinunter zum Zielelement. Bubbling-Ereignisse übergeben vom Zielelement an das Stammelement. Das Ereignisrouting in WPF wird ausführlicher unten in dieser Übersicht und in der Übersicht über Routingereignisse behandelt.

Tastatur- und Mausklassen

Zusätzlich zur Eingabe-API für die Basiselementklassen bieten die Keyboard- und Mouse-Klassen eine zusätzliche API für das Arbeiten mit Tastatur- und Mauseingaben.

Beispiele für die Eingabe-API für die Keyboard-Klasse sind die Modifiers-Eigenschaft, die die aktuell gedrückte ModifierKeys zurückgibt, und die IsKeyDown-Methode, die ermittelt, ob eine angegebene Taste gedrückt wird.

Das folgende Beispiel verwendet die GetKeyStates-Methode, um festzustellen, ob sich ein Key-Element im Zustand „gedrückt“ befindet.

// Uses the Keyboard.GetKeyStates to determine if a key is down.
// A bitwise AND operation is used in the comparison.
// e is an instance of KeyEventArgs.
if ((Keyboard.GetKeyStates(Key.Return) & KeyStates.Down) > 0)
{
    btnNone.Background = Brushes.Red;
}
' Uses the Keyboard.GetKeyStates to determine if a key is down.
' A bitwise AND operation is used in the comparison. 
' e is an instance of KeyEventArgs.
If (Keyboard.GetKeyStates(Key.Return) And KeyStates.Down) > 0 Then
    btnNone.Background = Brushes.Red

Beispiele für die Eingabe-API für die Mouse-Klasse sind MiddleButton für die Abfrage des Status der mittleren Maustaste und DirectlyOver für die Abfrage des Elements, über dem sich der Mauszeiger aktuell befindet.

Im folgenden Beispiel wird ermittelt, ob sich das LeftButton-Element auf der Maus im Zustand Pressed befindet.

if (Mouse.LeftButton == MouseButtonState.Pressed)
{
    UpdateSampleResults("Left Button Pressed");
}
If Mouse.LeftButton = MouseButtonState.Pressed Then
    UpdateSampleResults("Left Button Pressed")
End If

Die Klassen Mouse und Keyboard werden in diesem Überblick ausführlicher behandelt.

Stifteingabe

WPF verfügt über integrierte Unterstützung für das Stylus-Element. Stylus ist eine Stifteingabe, die durch den Tablet-PC bekannt wurde. WPF-Anwendungen können den Stift als Maus behandeln, indem Sie die Maus-API verwenden. WPF stellt jedoch auch eine Stiftgeräteabstraktion zur Verfügung, die ein Modell ähnlich der Tastatur und der Maus verwendet. Alle dem Stift zugehörigen APIs enthalten den Begriff „Stylus“ (Stift oder Tablettstift).

Da der Stift als Maus fungieren kann, können Anwendungen, die nur die Mauseingabe unterstützen, noch immer ein gewisses Maß an automatischer Unterstützung für den Stift erhalten. Wenn der Stift auf diese Weise verwendet wird, bekommt die Anwendung die Gelegenheit, das entsprechende Stiftereignis zu behandeln und behandelt dann das entsprechende Mausereignis. Darüber hinaus sind Dienste auf höherer Ebene (z.B. Freihandeingabe) noch immer über die Stift-Geräteabstraktion verfügbar. Weitere Informationen zur Freihandeingabe finden Sie unter Erste Schritte mit Freihandeingaben.

Ereignisrouting

Ein FrameworkElement kann andere Elemente als untergeordnete Elemente im Inhaltsmodell enthalten, wodurch eine Struktur von Elementen entsteht. In WPF kann das übergeordnete Element an Eingaben teilnehmen, die an seine untergeordneten Elemente oder andere Nachfolger gerichtet sind, indem Ereignisse weitergegeben werden. Dies ist besonders nützlich für die Erstellung von Steuerelementen aus kleineren Steuerelementen, ein Prozess, der als „Steuerelementkomposition“ oder „Komposition“ bekannt ist. Weitere Informationen zu Elementstrukturen und dazu, wie Elementstrukturen mit Ereignisrouten zusammenhängen, finden Sie unter Strukturen in WPF.

Das Ereignisrouting ist der Prozess, in dem Ereignisse an mehrere Elemente weitergeleitet werden, sodass ein bestimmtes Objekt oder Element entlang der Route einem Ereignis eine signifikante Antwort (durch Behandlung) anbieten kann, die sonst von einem anderen Element hätte stammen können. Routingereignisse verwenden einen von drei Routingmechanismen: direkt, Bubbling und Tunneln. Beim direkten Routing ist das Quellelement das einzige benachrichtigte Element, und das Ereignis wird nicht an andere Elemente weitergeleitet. Das direkte Routingereignis bietet jedoch noch einige zusätzliche Funktionen, die im Gegensatz zu CLR-Standardereignissen nur für Routingereignisse vorhanden sind. Bubbling arbeitet sich in der Elementstruktur nach oben, indem zuerst das Element benachrichtigt wird, von dem das Ereignis stammt, und anschließend das übergeordnete Element usw. Tunneling beginnt am Stamm der Elementstruktur, arbeitet sich nach unten und endet mit dem ursprünglichen Quellelement. Weitere Informationen zu Routingereignissen finden Sie unter Übersicht über Routingereignisse.

WPF-Eingabeereignisse treten generell in Paaren auf, die aus einem Tunnelingereignis und einem Bubblingereignis bestehen. Tunneling-Ereignisse unterscheiden sich von Bubbling-Ereignissen im Präfix „Preview“. Beispielsweise ist PreviewMouseMove die Tunnelingversion eines Mausbewegungsereignisses, und MouseMove ist die Bubblingversion dieses Ereignisses. Diese Ereignispaarung ist eine Konvention, die auf Elementebene implementiert ist, und keine inhärente Funktion des WPF-Ereignissystems. Weitere Informationen finden Sie im Abschnitt „Eingabeereignisse in WPF“ in Übersicht über Routingereignisse.

Behandeln von Eingabeereignissen

Um Eingaben für ein Element zu erhalten, muss ein Ereignishandler mit diesem speziellen Ereignis verknüpft sein. In XAML ist dies einfach: Sie verweisen auf den Namen des Ereignisses als ein Attribut des Elements, das auf dieses Ereignis lauscht. Legen Sie anschließend den Wert des Attributs auf den Namen des Ereignishandlers, den Sie basierend auf einen Delegaten definieren, fest. Der Ereignishandler muss z. B. in Code wie C# geschrieben werden und kann in einer CodeBehind-Datei eingebunden werden.

Tastaturereignisse treten auf, wenn das Betriebssystem Tastaturaktionen meldet, die auftreten, während sich der Tastaturfokus auf einem Element befindet. Maus- und Stiftereignisse lassen sich in zwei Kategorien unterteilen: Ereignisse, die Änderungen der Zeigerposition relativ zum Element melden sowie Ereignisse, die Änderungen im Status der Geräteschaltflächen melden.

Beispiel eines Tastatureingabeereignisses

Das folgende Beispiel überwacht das Drücken der Nach-Links-Taste. Ein StackPanel-Element wird erstellt, das über ein Button-Element verfügt. Der Button-Instanz wird ein Ereignishandler hinzugefügt, der das Drücken der NACH-LINKS-TASTE überwacht.

Im ersten Abschnitt des Beispiels werden StackPanel und Button erstellt, und der Ereignishandler für KeyDown wird angefügt.

<StackPanel>
  <Button Background="AliceBlue"
          KeyDown="OnButtonKeyDown"
          Content="Button1"/>
</StackPanel>
// Create the UI elements.
StackPanel keyboardStackPanel = new StackPanel();
Button keyboardButton1 = new Button();

// Set properties on Buttons.
keyboardButton1.Background = Brushes.AliceBlue;
keyboardButton1.Content = "Button 1";

// Attach Buttons to StackPanel.
keyboardStackPanel.Children.Add(keyboardButton1);

// Attach event handler.
keyboardButton1.KeyDown += new KeyEventHandler(OnButtonKeyDown);
' Create the UI elements.
Dim keyboardStackPanel As New StackPanel()
Dim keyboardButton1 As New Button()

' Set properties on Buttons.
keyboardButton1.Background = Brushes.AliceBlue
keyboardButton1.Content = "Button 1"

' Attach Buttons to StackPanel.
keyboardStackPanel.Children.Add(keyboardButton1)

' Attach event handler.
AddHandler keyboardButton1.KeyDown, AddressOf OnButtonKeyDown

Der zweite Abschnitt ist in Code geschrieben und definiert den Ereignishandler. Wenn die NACH-LINKS-TASTE gedrückt wird und das Button-Element den Tastaturfokus besitzt, wird der Handler ausgeführt, und die Background-Farbe von Button wird geändert. Wenn die Taste gedrückt wird, die nicht die NACH-LINKS-TASTE ist, wird die Background-Farbe von Button wieder auf die Ausgangsfarbe zurückgesetzt.

private void OnButtonKeyDown(object sender, KeyEventArgs e)
{
    Button source = e.Source as Button;
    if (source != null)
    {
        if (e.Key == Key.Left)
        {
            source.Background = Brushes.LemonChiffon;
        }
        else
        {
            source.Background = Brushes.AliceBlue;
        }
    }
}
Private Sub OnButtonKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
    Dim source As Button = TryCast(e.Source, Button)
    If source IsNot Nothing Then
        If e.Key = Key.Left Then
            source.Background = Brushes.LemonChiffon
        Else
            source.Background = Brushes.AliceBlue
        End If
    End If
End Sub

Beispiel für Mauseingabeereignisse

Im folgenden Beispiel wird die Background-Farbe eines Button-Elements geändert, wenn der Mauszeiger auf das Button-Element zeigt. Die Background-Farbe wird wiederhergestellt, wenn die Maus das Button-Element verlässt.

Im ersten Abschnitt des Beispiels werden die StackPanel- und Button-Steuerelemente erstellt und die Ereignishandler für die MouseEnter-und MouseLeave-Ereignisse an Button angefügt.

<StackPanel>
  <Button Background="AliceBlue"
          MouseEnter="OnMouseExampleMouseEnter"
          MouseLeave="OnMosueExampleMouseLeave">Button
          
  </Button>
</StackPanel>
// Create the UI elements.
StackPanel mouseMoveStackPanel = new StackPanel();
Button mouseMoveButton = new Button();

// Set properties on Button.
mouseMoveButton.Background = Brushes.AliceBlue;
mouseMoveButton.Content = "Button";

// Attach Buttons to StackPanel.
mouseMoveStackPanel.Children.Add(mouseMoveButton);

// Attach event handler.
mouseMoveButton.MouseEnter += new MouseEventHandler(OnMouseExampleMouseEnter);
mouseMoveButton.MouseLeave += new MouseEventHandler(OnMosueExampleMouseLeave);
' Create the UI elements.
Dim mouseMoveStackPanel As New StackPanel()
Dim mouseMoveButton As New Button()

' Set properties on Button.
mouseMoveButton.Background = Brushes.AliceBlue
mouseMoveButton.Content = "Button"

' Attach Buttons to StackPanel.
mouseMoveStackPanel.Children.Add(mouseMoveButton)

' Attach event handler.
AddHandler mouseMoveButton.MouseEnter, AddressOf OnMouseExampleMouseEnter
AddHandler mouseMoveButton.MouseLeave, AddressOf OnMosueExampleMouseLeave

Der zweite Abschnitt des Beispiels wird in Code geschrieben und definiert die Ereignishandler. Wenn die Maus auf das Button-Element zeigt, wird die Background-Farbe von Button in SlateGray geändert. Wenn die Maus das Button-Element verlässt, wird die Background-Farbe von Button zurück in AliceBlue geändert.

private void OnMouseExampleMouseEnter(object sender, MouseEventArgs e)
{
    // Cast the source of the event to a Button.
    Button source = e.Source as Button;

    // If source is a Button.
    if (source != null)
    {
        source.Background = Brushes.SlateGray;
    }
}
Private Sub OnMouseExampleMouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs)
    ' Cast the source of the event to a Button.
    Dim source As Button = TryCast(e.Source, Button)

    ' If source is a Button.
    If source IsNot Nothing Then
        source.Background = Brushes.SlateGray
    End If
End Sub
private void OnMosueExampleMouseLeave(object sender, MouseEventArgs e)
{
    // Cast the source of the event to a Button.
    Button source = e.Source as Button;

    // If source is a Button.
    if (source != null)
    {
        source.Background = Brushes.AliceBlue;
    }
}
Private Sub OnMosueExampleMouseLeave(ByVal sender As Object, ByVal e As MouseEventArgs)
    ' Cast the source of the event to a Button.
    Dim source As Button = TryCast(e.Source, Button)

    ' If source is a Button.
    If source IsNot Nothing Then
        source.Background = Brushes.AliceBlue
    End If
End Sub

Texteingabe

Mit dem TextInput-Ereignis können Sie die Texteingabe geräteunabhängig überwachen. Die Tastatur dient primär der Texteingabe, jedoch können Sie auch durch die Sprache, handschriftlich oder mit anderen Eingabegeräten Texteingabe generieren.

Für Tastatureingaben sendet WPF zuerst die entsprechenden KeyDown/KeyUp-Ereignisse. Wenn diese Ereignisse nicht verarbeitet werden und die Taste textbasiert ist (und keine Steuerungstaste, z. B. Richtungspfeile oder Funktionstasten), dann wird ein TextInput-Ereignis ausgelöst. Es gibt nicht immer eine einfache Eins-zu-Eins-Zuordnung zwischen KeyDown/KeyUp- und TextInput-Ereignissen, da mehrere Tastatureingaben ein einzelnes Zeichen der Texteingabe und einzelne Tastatureingaben Zeichenfolgen mit mehreren Zeichen generieren können. Dies gilt insbesondere für Sprachen wie Chinesisch, Japanisch und Koreanisch die Eingabemethoden-Editor (IMEs) zum Generieren von Tausenden von möglichen Zeichen in ihrem jeweiligen Alphabet verwenden.

Wenn WPF ein KeyUp/KeyDown-Ereignis sendet, wird Key auf Key.System festgelegt, wenn die Tastatureingaben Teil eines TextInput-Ereignisses werden könnten (wenn z. B. ALT+S gedrückt wird). Dadurch kann Code in einem KeyDown-Ereignishandler auf Key.System prüfen und, falls gefunden, die Verarbeitung dem Handler des anschließend ausgelösten TextInput-Ereignisses überlassen. In diesen Fällen können die unterschiedlichen Eigenschaften des TextCompositionEventArgs-Arguments verwendet werden, um die ursprüngliche Tastatureingabe zu bestimmen. Wenn ein IME aktiv ist, hat Key den Wert von Key.ImeProcessed, und ImeProcessedKey gibt den ursprünglichen Tastatureingabe oder die ursprünglichen Tastatureingaben an.

Im folgenden Beispiel wird ein Handler für das Click-Ereignis und ein Handler für das KeyDown-Ereignis definiert.

Das erste Segment des Codes oder Markups erstellt die Benutzeroberfläche.

<StackPanel KeyDown="OnTextInputKeyDown">
  <Button Click="OnTextInputButtonClick"
          Content="Open" />
  <TextBox> . . . </TextBox>
</StackPanel>
// Create the UI elements.
StackPanel textInputStackPanel = new StackPanel();
Button textInputeButton = new Button();
TextBox textInputTextBox = new TextBox();
textInputeButton.Content = "Open";

// Attach elements to StackPanel.
textInputStackPanel.Children.Add(textInputeButton);
textInputStackPanel.Children.Add(textInputTextBox);

// Attach event handlers.
textInputStackPanel.KeyDown += new KeyEventHandler(OnTextInputKeyDown);
textInputeButton.Click += new RoutedEventHandler(OnTextInputButtonClick);
' Create the UI elements.
Dim textInputStackPanel As New StackPanel()
Dim textInputeButton As New Button()
Dim textInputTextBox As New TextBox()
textInputeButton.Content = "Open"

' Attach elements to StackPanel.
textInputStackPanel.Children.Add(textInputeButton)
textInputStackPanel.Children.Add(textInputTextBox)

' Attach event handlers.
AddHandler textInputStackPanel.KeyDown, AddressOf OnTextInputKeyDown
AddHandler textInputeButton.Click, AddressOf OnTextInputButtonClick

Das zweite Segment des Codes enthält die Ereignishandler.

private void OnTextInputKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.O && Keyboard.Modifiers == ModifierKeys.Control)
    {
        handle();
        e.Handled = true;
    }
}

private void OnTextInputButtonClick(object sender, RoutedEventArgs e)
{
    handle();
    e.Handled = true;
}

public void handle()
{
    MessageBox.Show("Pretend this opens a file");
}
Private Sub OnTextInputKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
    If e.Key = Key.O AndAlso Keyboard.Modifiers = ModifierKeys.Control Then
        handle()
        e.Handled = True
    End If
End Sub

Private Sub OnTextInputButtonClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
    handle()
    e.Handled = True
End Sub

Public Sub handle()
    MessageBox.Show("Pretend this opens a file")
End Sub

Da Eingabeereignisse die Ereignisroute übergeben, erhält StackPanel die Eingabe unabhängig davon, welches Element über Tastaturfokus verfügt. Das TextBox-Steuerelement wird zuerst benachrichtigt, und der OnTextInputKeyDown-Handler wird nur dann aufgerufen, wenn TextBox die Eingabe nicht verarbeitet hat. Wenn das PreviewKeyDown-Ereignis anstelle des KeyDown-Ereignisses verwendet wird, wird der OnTextInputKeyDown-Handler zuerst aufgerufen.

In diesem Beispiel wird die Behandlungslogik zweimal geschrieben: einmal für STRG+O und nochmal für das Click-Ereignis der Schaltfläche. Anstatt die Eingabeereignisse direkt zu behandeln, können Sie dies mithilfe von Befehlen vereinfachen. Befehle werden in dieser Übersicht unter Befehlsübersicht erläutert.

Fingereingabe (Touch) und-Bearbeitung

Neue Hardware und API im Windows 7-Betriebssystem bieten Anwendungen die Möglichkeit, Eingabe von mehreren Berührungen gleichzeitig zu erhalten. WPF ermöglicht Anwendungen, Fingereingaben zu erkennen und ähnlich wie auf andere Eingaben zu reagieren, z. B. von einer Maus oder einer Tastatur, durch Auslösen von Ereignissen, wenn eine Fingereingabe erfolgt.

WPF macht zwei Typen von Ereignissen verfügbar, wenn eine Fingereingabe erfolgt: Berührungsereignisse und Bearbeitungsereignisse. Berührungsereignisse stellen Rohdaten zu jedem Finger auf einem Touchscreen und seiner Bewegung bereit. Bearbeitungsereignisse interpretieren die Eingabe als bestimmte Aktionen. Beide Typen von Ereignissen werden in diesem Abschnitt erläutert.

Voraussetzungen

Sie benötigen die folgenden Komponenten zur Entwicklung einer Anwendung, die auf Fingereingabe reagiert.

  • Visual Studio 2010.

  • Windows 7.

  • Ein Gerät, z.B. ein Touchscreen, das Windows Touch unterstützt

Begriff

Die folgenden Begriffe werden verwendet, wenn die Fingereingabe behandelt wird.

  • Touch (Fingereingabe) ist ein Typ von Benutzereingabe, der von Windows 7 erkannt wird. In der Regel wird die Fingereingabe initiiert, indem ein berührungsempfindlicher Bildschirm mit Fingern berührt wird. Beachten Sie, dass Geräte wie Touchpads, die auf Laptops gang und gäbe sind, keine Fingereingabe unterstützen, wenn das Gerät lediglich die Position und die Bewegung des Fingers als Mauseingabe konvertiert.

  • Multitouch (Mehrfingereingabe) ist Berührung, die gleichzeitig von mehreren Punkten erfolgt. Windows 7 und WPF unterstützen die Mehrfingereingabe. Wann immer die Fingereingabe in der Dokumentation zu WPF erläutert wird, gelten die Konzepte auch für die Mehrfingereingabe.

  • Ein Manipulation tritt auf, wenn die Berührung als physische Aktion interpretiert wird, die auf ein Objekt angewendet wird. In WPF interpretieren Bearbeitungsereignisse die Eingabe als Übersetzungs-, Erweiterungs- und Drehungsmanipualtion.

  • Ein touch device stellt ein Gerät dar, das Fingereingabe erzeugt, z.B. ein einzelner Finger auf einem Touchscreen.

Steuerelemente, die auf Fingereingabe reagieren

Die folgenden Steuerelemente können gescrollt werden, wenn Sie über Inhalt verfügen, der sich außerhalb der Ansicht befindet, indem Sie mit einem Finger über die Steuerelemente wischen.

ScrollViewer definiert die angefügte ScrollViewer.PanningMode-Eigenschaft, mit der Sie angeben können, ob Zweifingerverschiebung horizontal, vertikal, in beide Richtungen oder gar nicht aktiviert ist. Die ScrollViewer.PanningDeceleration-Eigenschaft gibt an, wie schnell sich das Scrollen verlangsamt, wenn der Benutzer den Finger vom Touchscreen nimmt. Die angefügte ScrollViewer.PanningRatio-Eigenschaft gibt das Verhältnis vom Scrollingversatz zum Verschiebebearbeitungsversatz an.

Berührungsereignisse

Die Basisklassen UIElement, UIElement3D und ContentElement definieren Ereignisse, die Sie abonnieren können, damit Ihre Anwendung auf Berührungen reagieren kann. Berührungsereignisse sind nützlich, wenn Ihre Anwendung Fingereingabe als etwas anderes als die Bearbeitung eines Objekts interpretiert. Beispielsweise würde eine Anwendung, mit der ein Benutzer mit einem oder mehreren Fingern zeichnen kann, Berührungsereignisse abonnieren.

Alle drei Klassen definieren die folgenden Ereignisse, die sich ähnlich verhalten, unabhängig von der definierenden Klasse.

Wie die Tastatur- und Maus-Ereignisse sind die Berührungsereignisse Routingereignisse. Die Ereignisse, die mit Preview beginnen, sind Tunneling-Ereignisse, und die Ereignisse, die mit Touch beginnen, sind Bubbling-Ereignisse. Weitere Informationen zu Routingereignissen finden Sie unter Übersicht über Routingereignisse. Wenn Sie diese Ereignisse verarbeiten, können Sie die Position der Eingabe relativ zu einem beliebigen Element ermitteln, indem Sie die GetTouchPoint- oder GetIntermediateTouchPoints-Methode aufrufen.

Um die Interaktion zwischen Berührungsereignissen zu verstehen, denken Sie an das Szenario, bei dem ein Benutzer einen Finger auf ein Element legt, den Finger im Element bewegt und anschließend den Finger vom Element wegnimmt. Die folgende Abbildung zeigt die Ausführung der Bubbling-Ereignisse (die Tunneling-Ereignisse werden der Einfachheit halber ausgelassen).

The sequence of touch events. Berührungsereignisse

Die folgende Liste beschreibt die Abfolge der Ereignisse in der vorherigen Abbildung.

  1. Das TouchEnter-Ereignis tritt einmalig auf, wenn der Benutzer das Element mit dem Finger berührt.

  2. Das TouchDown-Ereignis tritt ein Mal auf.

  3. Das TouchMove-Ereignis tritt mehrmals auf, da der Benutzer den Finger innerhalb des Elements bewegt.

  4. Das TouchUp-Ereignis tritt ein Mal auf, wenn der Benutzer den Finger vom Element nimmt.

  5. Das TouchLeave-Ereignis tritt ein Mal auf.

Wenn mehr als zwei Finger verwendet werden, treten die Ereignisse für jeden Finger auf.

Bearbeitungsereignisse

Für Fälle, in denen eine Anwendung einem Benutzer ermöglicht, ein Objekt zu bearbeiten, definiert die UIElement-Klasse Bearbeitungsereignisse. Im Gegensatz zu den Berührungsereignissen, die einfach die Position der Berührung melden, melden die Bearbeitungsereignisse, wie die Eingabe interpretiert werden kann. Es gibt drei Arten von Manipulationen, Übersetzung, Erweiterung und Drehung. Die folgende Liste beschreibt, wie die drei Typen von Manipulationen aufgerufen werden.

  • Legen Sie einen Finger auf ein Objekt, und verschieben Sie den Finger über den Touchscreen, um eine Übersetzungsmanipulation aufzurufen. Dadurch wird in der Regel das Objekt verschoben.

  • Legen Sie zwei Finger auf ein Objekt, und bewegen Sie die Finger näher zusammen oder weiter auseinander, um eine Erweiterungsmanipulation aufzurufen. Dadurch wird in der Regel die Größe des Objekts geändert.

  • Legen Sie zwei Finger auf ein Objekt, und drehen Sie einen Finger um den jeweils anderen um eine Drehungsmanipulation aufzurufen. Dadurch wird in der Regel das Objekt gedreht.

Es kann mehr als eine Manipulation gleichzeitig geschehen.

Wenn Sie Objekte dazu bringen, auf Manipulationen anzusprechen, können Sie erreichen, dass das Objekt verzögert wird. Dadurch kann Ihr Objekt die physische Welt simulieren. Wenn Sie z.B. ein Buch über einen Tisch schieben, dann bewegt sich das Buch nach dem Loslassen weiter voran, wenn Sie nur kräftig genug anschieben. Mit WPF können Sie dieses Verhalten übernehmen, indem Sie Bearbeitungsereignisse auslösen,nachdem der Benutzer das Objekt losgelassen hat.

Informationen dazu, wie Sie eine Anwendung erstellen, mit der ein Benutzer ein Objekt bewegen, drehen und dessen Größe verändern kann, finden Sie unter Exemplarische Vorgehensweise: Erstellen der ersten Fingereingabeanwendung.

UIElement definiert die folgenden Bearbeitungsereignisse.

In der Standardeinstellung erhält ein UIElement keine diese Bearbeitungsereignisse. Um Bearbeitungsereignisse für ein UIElement zu empfangen, legen Sie UIElement.IsManipulationEnabled auf true fest.

Der Ausführungspfad von Bearbeitungsereignissen

Denken Sie an ein Szenario, in dem ein Benutzer ein Objekt „wirft“. Der Benutzer legt einen Finger auf das Objekt, bewegt den Finger etwas über den Touchscreen und hebt dann in der Bewegung den Finger. Dadurch bewegt sich das Objekt unter dem Finger des Benutzers und bewegt sich dann noch weiter, wenn der Benutzer den Finger hebt.

Die folgende Abbildung zeigt den Ausführungspfad von Bearbeitungsereignissen und wichtige Informationen zu jedem Ereignis.

The sequence of manipulation events. Bearbeitungsereignisse

Die folgende Liste beschreibt die Abfolge der Ereignisse in der vorherigen Abbildung.

  1. Das ManipulationStarting-Ereignis tritt ein, wenn der Benutzer das Objekt mit dem Finger berührt. Mit diesem Ereignis können Sie u. a. die ManipulationContainer-Eigenschaft festlegen. In den nachfolgenden Ereignissen ist die Position der Bearbeitung relativ zu ManipulationContainer. Bei anderen Ereignissen als ManipulationStarting ist diese Eigenschaft schreibgeschützt, sodass Sie diese Eigenschaft nur beim ManipulationStarting-Ereignis festlegen können.

  2. Anschließend tritt das ManipulationStarted-Ereignis auf. Dieses Ereignis meldet den Ursprung der Manipulation.

  3. Das ManipulationDelta Ereignis tritt mehrmals auf, wenn sich die Finger eines Benutzers auf einem Touchscreen bewegen. Die DeltaManipulation-Eigenschaft der ManipulationDeltaEventArgs-Klasse meldet, ob die Bearbeitung als Bewegung, Erweiterung oder Übersetzung interpretiert wird. Hier können Sie die meisten Bearbeitungen an einem Objekt durchführen.

  4. Das ManipulationInertiaStarting-Ereignis tritt auf, wenn die Finger des Benutzers den Kontakt mit dem Objekt verlieren. Mit diesem Ereignis können Sie die Verlangsamung der Bearbeitungen während der Verzögerung angeben. So kann Ihr Objekt unterschiedliche physikalische Bereiche oder Attribute Ihrer Wahl emulieren. Nehmen wir beispielsweise an, Ihre Anwendung enthält zwei Objekte, die Elemente in der realen Welt darstellen, und eines massiger als das andere ist. Sie können veranlassen, dass das massige Objekt schneller verlangsamt wird als das leichtere Objekt

  5. Das Ereignis ManipulationDelta tritt mehrfach auf, wenn keine Bewegung stattfindet. Beachten Sie, dass dieses Ereignis auftritt, wenn der Benutzer seine Finger über den Touchscreen bewegt, und wenn WPF Bewegungslosigkeit simuliert. Mit anderen Worten: ManipulationDelta tritt vor und nach dem ManipulationInertiaStarting-Ereignis auf. Die ManipulationDeltaEventArgs.IsInertial-Eigenschaft meldet, ob das ManipulationDelta-Ereignis während der Bewegungslosigkeit eintritt, sodass Sie diese Eigenschaft überprüfen und je nach Wert verschiedene Aktionen durchführen können.

  6. Das ManipulationCompleted-Ereignis tritt auf, wenn die Bearbeitung und jegliche Bewegungslosigkeit endet. Das heißt, nachdem alle ManipulationDelta-Ereignisse aufgetreten sind, tritt das ManipulationCompleted-Ereignis auf, um zu signalisieren, dass die Bearbeitung abgeschlossen ist.

UIElement definiert auch das ManipulationBoundaryFeedback-Ereignis. Dieses Ereignis tritt auf, wenn die ReportBoundaryFeedback-Methode im ManipulationDelta-Ereignis aufgerufen wird. Das ManipulationBoundaryFeedback-Ereignis ermöglicht Anwendungen oder Komponenten die Bereitstellung von visuellem Feedback, wenn ein Objekt an eine Grenze stößt. Die Window-Klasse verarbeitet z. B. das ManipulationBoundaryFeedback-Ereignis, um eine leichte Bewegung des Fensters zu bewirken, wenn sein Rand erreicht wird.

Sie können die Bearbeitung abbrechen, indem Sie die Cancel-Methode für die Ereignisargumente in einem beliebigen Bearbeitungsereignis außer dem ManipulationBoundaryFeedback-Ereignis aufrufen. Wenn Sie Cancel aufrufen, werden die Bearbeitungsereignisse nicht mehr ausgelöst, und es treten Mausereignisse für Berührungen auf. Die folgende Tabelle beschreibt die Beziehung zwischen dem Zeitpunkt, an dem die Bearbeitung abgebrochen wird, und den Mausereignissen, die auftreten.

Das Ereignis zum Abbruch, das aufgerufen wird Die Mausereignisse, die für die Eingabe auftreten, die bereits aufgetreten sind
ManipulationStarting und ManipulationStarted Ereignisse mit gedrückter Maustaste
ManipulationDelta Ereignisse mit gedrückter Maustaste und beim Verschieben der Maus
ManipulationInertiaStarting und ManipulationCompleted Ereignisse mit gedrückter Maustaste, beim Verschieben der Maus und beim Loslassen der Maustaste

Die Methode gibt false zurück, und die Eingabe löst keine Mausereignisse aus, wenn Sie Cancel aufrufen, wenn für die Bearbeitung Bewegungslosigkeit vorliegt.

Die Beziehung zwischen Berührungs- und Bearbeitungsereignissen

Ein UIElement kann immer Toucheingabeereignisse empfangen. Wenn die IsManipulationEnabled-Eigenschaft auf true festgelegt ist, kann ein UIElement sowohl Berührungs- als auch Bearbeitungsereignisse empfangen. Wenn das TouchDown-Ereignis nicht verarbeitet wird (d. h. die Handled-Eigenschaft false ist), erfasst die Bearbeitungslogik die Berührung des Elements und generiert die Bearbeitungsereignisse. Wenn die Handled-Eigenschaft im TouchDown-Ereignis auf true festgelegt ist, generiert die Bearbeitungslogik keine Bearbeitungsereignisse. Die folgende Abbildung zeigt die Beziehung zwischen Berührungs- und Bearbeitungsereignissen.

Relationship between touch and manipulation events Berührungs- und Bearbeitungsereignisse

Die folgende Liste beschreibt die Beziehung zwischen Berührungs- und Bearbeitungsereignissen, die in der folgenden Abbildung dargestellt ist.

Fokus

Es gibt zwei Hauptkonzepte, die den Fokus in WPF betreffen: Tastaturfokus und logischer Fokus.

Tastaturfokus

Der Tastaturfokus bezieht sich auf das Element, das Tastatureingaben empfängt. Es kann nur ein Element auf dem gesamten Desktop geben, das über den Tastaturfokus verfügt. In WPF wird für das Element, das den Tastaturfokus besitzt, IsKeyboardFocused auf true festgelegt. Die statische Keyboard-Methode FocusedElement gibt das Element zurück, das aktuell den Tastaturfokus besitzt.

Der Tastaturfokus kann durch Wechseln mit der Tabulatortaste zu einem Element abgerufen werden oder durch Klicken mit der Maus auf bestimmte Elemente, z. B. auf ein TextBox-Element. Der Tastaturfokus kann auch programmgesteuert mit der Focus-Methode der Keyboard-Klasse abgerufen werden. Focus versucht, dem angegebenen Element den Tastaturfokus zu geben. Das von Focus zurückgegebene Element ist das Element, das aktuell den Tastaturfokus besitzt.

Damit ein Element den Tastaturfokus erhält, müssen die Focusable- und IsVisible-Eigenschaften auf true festgelegt sein. Bei einigen Klassen, z. B. Panel, ist Focusable standardmäßig auf false festgelegt. Deshalb müssen Sie möglicherweise diese Eigenschaft auf true festlegen, wenn dieses Element den Fokus erhalten soll.

Im folgenden Beispiel wird Focus verwendet, um den Tastaturfokus für ein Button-Element festzulegen. Es wird empfohlen, den anfänglichen Fokus in einer Anwendung im Loaded-Ereignishandler festzulegen.

private void OnLoaded(object sender, RoutedEventArgs e)
{
    // Sets keyboard focus on the first Button in the sample.
    Keyboard.Focus(firstButton);
}
Private Sub OnLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
    ' Sets keyboard focus on the first Button in the sample.
    Keyboard.Focus(firstButton)
End Sub

Weitere Informationen über den Tastaturfokus finden Sie unter Fokus – Übersicht.

Logischer Fokus

Der logische Fokus bezieht sich auf das FocusManager.FocusedElement in einem Fokusbereich. Es können mehrere Elemente vorhanden sein, die über logischen Fokus in einer Anwendung verfügen, jedoch kann es nur ein Element geben, das den logischen Fokus in einem bestimmten Fokusbereich besitzt.

Ein Fokusbereich ist ein Containerelement, das das FocusedElement innerhalb seines Bereichs nachverfolgt. Wenn der Fokus einen Fokusbereich verlässt, wird das Element den Tastaturfokus verlieren, jedoch behält es den logischen Fokus. Wenn der Fokus zum Fokusbereich zurückkehrt, wird das Fokuselement Tastaturfokus erhalten. Somit kann der Tastaturfokus zwischen mehreren Fokusbereichen geändert werden, aber es wird sichergestellt, dass das Fokuselement im Fokusbereich das Element bleibt, das über den Fokus verfügt, wenn dieser zurückgegeben wird.

Ein Element kann in XAML (Extensible Application Markup Language) in einen Fokusbereich umgewandelt werden, indem die angefügte FocusManager-Eigenschaft IsFocusScope auf true festgelegt wird, oder im Code, indem die angefügte Eigenschaft mit der Methode SetIsFocusScope festgelegt wird.

Das folgende Beispiel wandelt ein StackPanel-Element in einen Fokusbereich um, indem die angefügte IsFocusScope-Eigenschaft festgelegt wird.

<StackPanel Name="focusScope1" 
            FocusManager.IsFocusScope="True"
            Height="200" Width="200">
  <Button Name="button1" Height="50" Width="50"/>
  <Button Name="button2" Height="50" Width="50"/>
</StackPanel>
StackPanel focuseScope2 = new StackPanel();
FocusManager.SetIsFocusScope(focuseScope2, true);
Dim focuseScope2 As New StackPanel()
FocusManager.SetIsFocusScope(focuseScope2, True)

Klassen in WPF, die standardmäßig Fokusbereiche sind, sind Window, Menu, ToolBar und ContextMenu.

Ein Element, das über Tastaturfokus verfügt, besitzt ebenso logischen Fokus für den Fokusbereich, zu dem es gehört. Darum wird versucht, dem Element Tastaturfokus und logischen Fokus zu geben, indem der Fokus für ein Element mithilfe der Focus-Methode für die Keyboard-Klasse oder die Basiselementklassen festgelegt wird.

Um das Element zu bestimmen, das in einem Fokusbereich den Fokus besitzt, verwenden Sie GetFocusedElement. Um das Element mit Fokus für einen Fokusbereich zu ändern, verwenden Sie SetFocusedElement.

Weitere Informationen über den logischen Fokus finden Sie unter Fokus – Übersicht.

Mausposition

Die WPF-Eingabe-API stellt hilfreiche Informationen bezüglich Koordinatenbereichen bereit. Zum Beispiel ist die Koordinate (0,0) die Koordinate oben links, aber von welchem Element in der Struktur? Das Element, das das Eingabeziel ist? Das Element, an das Sie Ihren Ereignishandler angefügt haben? Oder doch etwas anderes? Um Verwechslungen zu vermeiden erfordert die WPF-Eingabe-API, dass Sie Ihren Verweisrahmen angeben, wenn Sie mit Koordinaten arbeiten, die über die Maus abgerufen werden. Die GetPosition-Methode gibt die Koordinaten des Mauszeigers relativ zum angegebenen Element zurück.

Mausaufzeichnung

Insbesondere Mausgeräte verfügen über modale Eigenschaften, die als Mausaufzeichnung bekannt sind. Die Mausaufzeichnung wird verwendet, um einen vorübergehenden Eingabestatus beizubehalten, wenn ein Drag & Drop-Vorgang gestartet wird, damit andere Vorgänge, einschließlich die nominale Position auf dem Bildschirm, nicht unbedingt auftreten. Während des Ziehens kann der Benutzer nicht klicken, ohne dass der Drag & Drop-Vorgang abgebrochen wird. Darum sind die meisten Mouseover-Cues nicht geeignet, während die Mausaufzeichnung durch die Drag-Quelle gehalten wird. Das Eingabesystem stellt APIs zur Verfügung, die den Mauserfassungsstatus bestimmen können, sowie APIs, die die Mauserfassung für ein bestimmtes Element erzwingen oder den Mauserfassungsstatus löschen können. Weitere Informationen zu Drag & Drop-Vorgängen finden Sie unter Übersicht über Drag & Drop.

Befehle

Befehle ermöglichen die Eingabebehandlung auf einer eher semantischeren Ebene als die Geräteeingabe. Befehle sind einfache Direktive, wie etwa Cut, Copy, Paste oder Open. Befehle sind nützlich für die Zentralisierung der Befehlslogik. Auf denselben Befehl kann über ein Menu, eine ToolBar oder eine Tastenkombination zugegriffen werden. Befehle stellen außerdem einen Mechanismus zum Deaktivieren von Steuerelementen bereit, wenn der Befehl nicht verfügbar ist.

RoutedCommand ist die WPF-Implementierung von ICommand. Wenn ein RoutedCommand ausgeführt wird, wird für das Befehlsziel ein PreviewExecuted- und ein Executed-Ereignis ausgelöst, die die Elementstruktur wie andere Eingaben als Tunneling- und Bubblingereignisse durchlaufen. Wenn ein Befehlsziel nicht festgelegt ist, wird das Element mit dem Tastaturfokus das Befehlsziel sein. Die Logik, die den Befehl ausführt, ist an eine CommandBinding angefügt. Wenn ein Executed-Ereignis eine CommandBinding für diesen spezifischen Befehl erreicht, wird der ExecutedRoutedEventHandler für die CommandBinding aufgerufen. Dieser Handler führt die Aktion des Befehls aus.

Weitere Informationen über Befehle finden Sie unter Befehlsübersicht.

WPF stellt eine Bibliothek allgemeiner Befehle bereit, die aus ApplicationCommands, MediaCommands, ComponentCommands, NavigationCommands und EditingCommands besteht. Sie können auch eigene Befehle definieren.

Im folgenden Beispiel wird gezeigt, wie ein MenuItem eingerichtet wird, damit der Befehl Paste für TextBox mit der Annahme, dass TextBox über den Tastaturfokus verfügt, aufgerufen wird, wenn darauf geklickt wird.

<StackPanel>
  <Menu>
    <MenuItem Command="ApplicationCommands.Paste" />
  </Menu>
  <TextBox />
</StackPanel>
// Creating the UI objects
StackPanel mainStackPanel = new StackPanel();
TextBox pasteTextBox = new TextBox();
Menu stackPanelMenu = new Menu();
MenuItem pasteMenuItem = new MenuItem();

// Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem);
mainStackPanel.Children.Add(stackPanelMenu);
mainStackPanel.Children.Add(pasteTextBox);

// Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste;

// Setting the command target to the TextBox
pasteMenuItem.CommandTarget = pasteTextBox;
' Creating the UI objects
Dim mainStackPanel As New StackPanel()
Dim pasteTextBox As New TextBox()
Dim stackPanelMenu As New Menu()
Dim pasteMenuItem As New MenuItem()

' Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem)
mainStackPanel.Children.Add(stackPanelMenu)
mainStackPanel.Children.Add(pasteTextBox)

' Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste

Weitere Informationen zu Befehlen in WPF finden Sie in der Befehlsübersicht.

Das Eingabesystem und die Basiselemente

Eingabeereignisse, etwa die angefügten Ereignisse, die von den Klassen Mouse, Keyboard und Stylus definiert sind, werden vom Eingabesystem ausgelöst und auf Grundlage von Treffertests für die visuelle Struktur zur Laufzeit in eine bestimmte Position im Objektmodell eingefügt.

Jedes der Ereignisse, die Mouse, Keyboardund Stylus als angefügtes Ereignis definieren, wird auch von den Basiselementklassen UIElement und ContentElement als neues geroutetes Ereignis erneut bereitgestellt. Die Basiselement-Routingereignisse werden von Klassen generiert, die das ursprüngliche angefügte Ereignis behandeln und die Ereignisdaten wiederverwenden.

Wenn das Eingabeereignis einem bestimmten Quellelement durch seine Implementierung des Eingabeereignisses des Basiselements zugeordnet wird, kann es durch den Rest einer Ereignisroute weitergeleitet werden, die auf einer Kombination von logischen und visuellen Strukturobjekten basiert und vom Anwendungscode behandelt wird. Im Allgemeinen ist es einfacher, diese auf das Gerät bezogenen Eingabeereignisse mithilfe von Routingereignissen für UIElement und ContentElement zu behandeln, da Sie jeweils in XAML und im Code intuitivere Ereignishandlersyntax verwenden können. Sie könnten stattdessen das angefügte Ereignis behandeln, das den Prozess initiiert hat, jedoch würden Sie auf Probleme stoßen: das angefügte Ereignis kann möglicherweise durch die Behandlung der Basiselementklasse behandelt markiert werden, und Sie müssen Accessormethoden verwenden, anstatt die richtige Ereignissyntax, um Handler für angefügte Ereignisse anzufügen.

Nächste Schritte

Sie kennen nun verschiedene Methoden, um Eingabe in WPF zu verarbeiten. Sie sollten auch ein tieferes Verständnis der verschiedenen Typen von Eingabeereignissen und Routingereignismechanismen haben, die von WPF genutzt werden.

Es gibt zusätzliche Ressourcen, die WPF-Frameworkelemente und das Ereignisrouting detaillierter beschreiben. In den folgenden Übersichten finden Sie weitere Informationen: Befehlsübersicht, Fokus – Übersicht, Übersicht über Basiselemente, Strukturen in WPF und Übersicht über Routingereignisse.

Siehe auch