Freigeben über


Übersicht über Eingaben

Das Windows Presentation Foundation (WPF)-Subsystem bietet eine leistungsstarke API zum Abrufen von Eingaben von einer Vielzahl von Geräten, einschließlich Maus, Tastatur, Toucheingabe und Eingabestift. In diesem Thema werden die von WPF bereitgestellten Dienste beschrieben und die Architektur der Eingabesysteme erläutert.

Eingabe-API

Die primäre Eingabe-API-Gefährdung wird in den Basiselementklassen gefunden: UIElement, , ContentElement, FrameworkElementund FrameworkContentElement. Weitere Informationen zu den Basiselementen finden Sie unter "Übersicht über Basiselemente". Diese Klassen bieten Funktionen für Eingabeereignisse im Zusammenhang mit Tastendrucken, Maustasten, Mausrad, Mausbewegung, Fokusverwaltung und Mauserfassung, um einige zu nennen. Durch Das Platzieren der Eingabe-API auf die Basiselemente anstatt alle Eingabeereignisse als Dienst zu behandeln, ermöglicht die Eingabearchitektur, dass die Eingabeereignisse von einem bestimmten Objekt in der Benutzeroberfläche stammen und ein Ereignisroutingschema unterstützt wird, bei dem mehrere Elemente die Möglichkeit haben, ein Eingabeereignis zu behandeln. Viele Eingabeereignisse verfügen über ein Ereignispaar, das ihnen zugeordnet ist. Das Key Down-Ereignis ist beispielsweise mit den KeyDown Ereignissen und PreviewKeyDown Ereignissen verknüpft. Der Unterschied bei diesen Ereignissen besteht darin, wie sie an das Zielelement weitergeleitet werden. Vorschauereignisse tunneln die Elementstruktur vom Stammelement bis zum Zielelement. Bubbling-Ereignisse bubbling von dem Zielelement bis zum Stammelement. Das Ereignisrouting in WPF wird weiter unten in dieser Übersicht und in der Übersicht über Routingereignisse erläutert.

Tastatur- und Mausklassen

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

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

Im folgenden Beispiel wird die GetKeyStates Methode verwendet, um zu ermitteln, ob sich ein Key Objekt im Abwärtszustand 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 der Mouse-Klasse sind MiddleButton, die den Zustand der mittleren Maustaste abruft, und DirectlyOver, das Element, über dem der Mauszeiger sich derzeit befindet.

Im folgenden Beispiel wird ermittelt, ob sich die LeftButton Maus im Pressed Zustand befindet.

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

Die Mouse und Keyboard Klassen werden in dieser Übersicht ausführlicher behandelt.

Stifteingabe

WPF bietet integrierte Unterstützung für Stylus. Der Stylus ist eine Stifteingabe, die durch das Tablet-PC populär geworden ist. WPF-Anwendungen können den Eingabestift mithilfe der Maus-API als Maus behandeln. WPF macht aber auch eine Eingabestift-Gerätestraktion verfügbar, die ein Modell ähnlich der Tastatur und Maus verwendet. Alle eingabestiftbezogenen APIs enthalten das Wort "Eingabestift".

Da der Eingabestift als Maus fungieren kann, können Anwendungen, die nur Mauseingaben unterstützen, trotzdem eine gewisse Unterstützung für Eingabestifte automatisch erhalten. Wenn der Eingabestift auf eine solche Weise verwendet wird, erhält die Anwendung die Möglichkeit, das entsprechende Eingabestiftereignis zu behandeln und dann das entsprechende Mausereignis zu behandeln. Darüber hinaus sind Dienste auf höherer Ebene wie Freihandeingaben auch über die Eingabestift-Abstraktion verfügbar. Weitere Informationen zu Freihandeingaben als Eingabe finden Sie unter "Erste Schritte mit Freihand".

Ereignisrouting

A FrameworkElement kann andere Elemente als untergeordnete Elemente im Inhaltsmodell enthalten und eine Struktur von Elementen bilden. In WPF kann das übergeordnete Element an eingaben teilnehmen, die an seine untergeordneten Elemente oder andere untergeordnete Elemente weitergeleitet werden, indem Ereignisse übergeben werden. Dies ist besonders hilfreich beim Erstellen von Steuerelementen aus kleineren Steuerelementen, einem Prozess, der als "Steuerelementkomposition" oder "Compositing" bezeichnet wird. Weitere Informationen zu Elementstrukturen und zur Beziehung von Elementstrukturen zu Ereignisrouten finden Sie unter "Trees in WPF".

Das Ereignisrouting ist der Prozess der Weiterleitung von Ereignissen an mehrere Elemente, sodass ein bestimmtes Objekt oder Element auf der Route auswählen kann, auf ein Ereignis, das möglicherweise von einem anderen Element stammt, signifikant zu reagieren (durch die Behandlung). Routingereignisse verwenden einen von drei Routingmechanismen: direktes, Bubbling und Tunneling. Im direkten Routing ist das Quellelement das einzige benachrichtigte Element, und das Ereignis wird nicht an andere Elemente weitergeleitet. Das direkte Routingereignis bietet jedoch weiterhin einige zusätzliche Funktionen, die nur für Routingereignisse im Gegensatz zu standard-CLR-Ereignissen vorhanden sind. Bubbling durchläuft die Elementstruktur von unten nach oben, indem zuerst das Element benachrichtigt wird, von dem das Ereignis stammt, dann das übergeordnete Element und so weiter. Tunneling beginnt am Stamm der Elementstruktur und arbeitet sich nach unten und endet mit dem ursprünglichen Quell-Element. Weitere Informationen zu Routingereignissen finden Sie unter "Übersicht über Routingereignisse".

WPF-Eingabeereignisse treten in der Regel paarweise auf, bestehend aus einem Tunneling-Ereignis und einem Bubble-Ereignis. Tunneling-Ereignisse unterscheiden sich durch den Präfix "Vorschau" von Bubbling-Ereignissen. Beispielsweise PreviewMouseMove ist die Tunnelversion eines Mausbewegungsereignisses und MouseMove die Bubbling-Version dieses Ereignisses. Diese Ereignispaarung ist eine Konvention, die auf Elementebene implementiert wird und keine inhärente Funktion des WPF-Ereignissystems ist. Ausführliche Informationen finden Sie im Abschnitt "WPF-Eingabeereignisse" in der Übersicht über Routingereignisse.

Behandeln von Eingabeereignissen

Um Eingaben für ein Element zu empfangen, muss ein Ereignishandler diesem bestimmten Ereignis zugeordnet sein. In XAML ist dies einfach: Sie verweisen auf den Namen des Ereignisses als Attribut des Elements, das auf dieses Ereignis lauscht. Anschließend legen Sie den Wert des Attributs auf den Namen des von Ihnen definierten Ereignishandlers fest, basierend auf einem Delegaten. Der Ereignishandler muss in Code wie C# geschrieben werden und kann in eine CodeBehind-Datei eingeschlossen werden.

Tastaturereignisse treten auf, wenn das Betriebssystem Wichtige Aktionen meldet, die auftreten, während sich der Tastaturfokus auf einem Element befindet. Maus- und Eingabestiftereignisse sind jeweils in zwei Kategorien unterteilt: Ereignisse, die Änderungen der Zeigerposition relativ zum Element melden, sowie Ereignisse, die Änderungen am Zustand von Geräteschaltflächen melden.

Beispiel für ein Tastatureingabeereignis

Das folgende Beispiel wartet auf das Drücken der Pfeil-nach-links-Taste. Ein StackPanel wird erstellt, das ein Button hat. Ein Ereignishandler, der auf das Drücken der linken Pfeiltaste lauscht, ist an die Button-Instanz angefügt.

Der erste Abschnitt des Beispiels erstellt StackPanel und Button und fügt den Ereignishandler für KeyDown hinzu.

<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 wird in Code geschrieben und definiert den Ereignishandler. Wenn die Nach-links-Taste gedrückt wird und der Button den Tastaturfokus besitzt, wird der Handler ausgeführt und die Background Farbe von Button geändert. Wenn eine Taste gedrückt wird, aber nicht die linke Pfeiltaste, wird die Background Farbe des Button wieder in die Startfarbe geändert.

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

Mouse Input-Ereignis (Beispiel)

Im folgenden Beispiel wird die Background-Farbe eines Button geändert, wenn der Mauszeiger in den Button eintritt. Die Background Farbe wird wiederhergestellt, wenn die Maus das Button verlässt.

Im ersten Abschnitt des Beispiels wird das StackPanel-Steuerelement und das Button-Steuerelement 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 in die ButtonZeichenfolge wechselt, wird die Background Farbe der Button Zeichenfolge geändert.SlateGray Wenn die Maus das Button verlässt, wird die Background-Farbe des Button wieder zu 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 auf geräteunabhängige Weise überwachen. Die Tastatur ist das primäre Mittel für die Texteingabe, aber Sprache, Handschrift und andere Eingabegeräte können auch Texteingaben generieren.

Bei der Tastatureingabe sendet WPF zuerst die entsprechenden KeyDown/KeyUp Ereignisse. Wenn diese Ereignisse nicht behandelt werden und die Taste textual ist (anstelle einer Steuertaste wie Richtungspfeile oder Funktionstasten), wird ein TextInput Ereignis ausgelöst. Es gibt nicht immer eine einfache 1:1-Zuordnung zwischen KeyDown/KeyUp und TextInput Ereignissen, da mehrere Tastenanschläge ein einzelnes Textzeichen generieren können, und einzelne Tastenanschläge können mehrstellige Textzeichenketten generieren. Dies gilt insbesondere für Sprachen wie Chinesisch, Japanisch und Koreanisch, die Eingabemethoden-Editoren (INPUT Method Editors, IMEs) verwenden, um tausende möglicher Zeichen in ihren entsprechenden Alphabeten zu generieren.

Wenn WPF ein KeyUp/KeyDown Ereignis sendet, wird Key auf Key.System gesetzt, wenn die Tastatureingaben Teil eines TextInput Ereignisses werden könnten (wenn z. B. ALT+S gedrückt wird). Auf diese Weise 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 verschiedenen Eigenschaften des TextCompositionEventArgs Arguments verwendet werden, um die ursprünglichen Tastaturanschläge zu bestimmen. Entsprechend weist ein IME Key den Wert von Key.ImeProcessed, und ImeProcessedKey gibt die ursprünglichen Tastenanschläge oder Tastenanschläge an.

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

Das erste Codesegment oder Markup 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 Codesegment 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 überblasen, empfängt die StackPanel Eingabe unabhängig davon, welches Element den Tastaturfokus hat. Das TextBox Steuerelement wird zuerst benachrichtigt, und der OnTextInputKeyDown Handler wird nur aufgerufen, wenn die TextBox Eingabe nicht behandelt wurde. Wenn das PreviewKeyDown Ereignis anstelle des KeyDown Ereignisses verwendet wird, wird der OnTextInputKeyDown Handler zuerst aufgerufen.

In diesem Beispiel wird die Verarbeitungslogik zweimal geschrieben – einmal für STRG+O und erneut für das Klickereignis der Schaltfläche. Dies kann mithilfe von Befehlen vereinfacht werden, anstatt die Eingabeereignisse direkt zu behandeln. Befehle werden in dieser Übersicht und in der Befehlsübersicht erläutert.

Berührung und Manipulation

Neue Hardware und API im Windows 7-Betriebssystem bieten Anwendungen die Möglichkeit, gleichzeitig Eingaben von mehreren Fingereingaben zu empfangen. WPF ermöglicht Anwendungen das Erkennen und Reagieren auf Toucheingaben ähnlich der Reaktion auf andere Eingaben, z. B. die Maus oder Tastatur, durch Auslösen von Ereignissen, wenn die Toucheingabe auftritt.

WPF macht zwei Arten von Ereignissen verfügbar, wenn die Toucheingabe auftritt: Touchereignisse und Manipulationsereignisse. Touchereignisse stellen Rohdaten zu jedem Finger auf einem Touchscreen und seiner Bewegung bereit. Manipulationsereignisse interpretieren die Eingabe als bestimmte Aktionen. Beide Arten von Ereignissen werden in diesem Abschnitt erläutert.

Voraussetzungen

Sie benötigen die folgenden Komponenten, um eine Anwendung zu entwickeln, die auf Toucheingabe reagiert.

  • Visual Studio 2010.

  • Windows 7.

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

Terminologie

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

  • Toucheingabe ist eine Art von Benutzereingabe, die von Windows 7 erkannt wird. In der Regel erfolgt die Berührung durch das Auflegen der Finger auf einen berührungsempfindlichen Bildschirm. Beachten Sie, dass Geräte wie ein Touchpad, das auf Laptopcomputern üblich ist, keine Toucheingabe unterstützen, wenn das Gerät lediglich die Position und Bewegung des Fingers als Mauseingabe konvertiert.

  • Multitouch ist eine Berührung, die von mehr als einem Punkt gleichzeitig erfolgt. Windows 7 und WPF unterstützen Multitouch. Wenn die Fingereingabe in der Dokumentation für WPF erläutert wird, gelten die Konzepte für Multitouch.

  • Eine Manipulation erfolgt, wenn die Toucheingabe als physische Aktion interpretiert wird, die auf ein Objekt angewendet wird. In WPF interpretieren Manipulationsereignisse Eingaben als Übersetzung, Erweiterung oder Drehungsmanipulation.

  • A touch device stellt ein Gerät dar, das Toucheingaben erzeugt, z. B. einen Finger auf einem Touchscreen.

Steuerelemente, die auf Toucheingabe reagieren

Die folgenden Steuerelemente können durch Ziehen eines Fingers über das Steuerelement gescrollt werden, wenn Inhalte vorhanden sind, die aus dem Sichtbereich hinausgescrollt sind.

Die ScrollViewer-Eigenschaft definiert die ScrollViewer.PanningMode angefügte Eigenschaft, mit der Sie angeben können, ob die Touchverschiebung horizontal, vertikal, sowohl horizontal als auch vertikal, oder weder horizontal noch vertikal aktiviert ist. Die ScrollViewer.PanningDeceleration Eigenschaft gibt an, wie schnell der Bildlauf verlangsamt wird, wenn der Benutzer den Finger vom Touchscreen hebt. Die ScrollViewer.PanningRatio angefügte Eigenschaft gibt das Verhältnis des Bildlaufoffsets an, um den Bearbeitungsoffset zu übersetzen.

Touch-Ereignisse

Die Basisklassen, UIElement, UIElement3Dund ContentElement, definieren Ereignisse, die Sie abonnieren können, damit Ihre Anwendung auf Toucheingabe reagiert. Touchereignisse sind nützlich, wenn Ihre Anwendung die Toucheingabe als etwas anderes interpretiert als das Bearbeiten eines Objekts. Eine Anwendung, die es einem Benutzer ermöglicht, mit einem oder mehreren Fingern zu zeichnen, würde z. B. Touchereignisse abonnieren.

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

Wie Tastatur- und Mausereignisse sind die Touchereignisse Routingereignisse. Die Ereignisse, die mit Preview beginnen, sind Tunnelereignisse, und die mit Touch beginnen, sind Bubbling-Ereignisse. Weitere Informationen zu Routingereignissen finden Sie unter "Übersicht über Routingereignisse". Wenn Sie diese Ereignisse behandeln, können Sie die Position der Eingabe relativ zu jedem Element abrufen, indem Sie die GetTouchPoint- oder GetIntermediateTouchPoints-Methode aufrufen.

Um die Interaktion zwischen den Touchereignissen zu verstehen, berücksichtigen Sie das Szenario, in dem ein Benutzer einen Finger auf ein Element legt, den Finger im Element bewegt und dann den Finger vom Element entfernt. Die folgende Abbildung zeigt die Ausführung der Bubbling-Ereignisse (die Tunnelereignisse werden aus Gründen der Einfachheit weggelassen).

Die Abfolge von Touchereignissen. Touchereignisse

In der folgenden Liste wird die Abfolge der Ereignisse in der vorherigen Abbildung beschrieben.

  1. Das TouchEnter Ereignis tritt einmal auf, wenn der Benutzer einen Finger auf das Element legt.

  2. Das TouchDown Ereignis tritt einmal auf.

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

  4. Das TouchUp Ereignis tritt einmal auf, wenn der Benutzer den Finger vom Element hebt.

  5. Das TouchLeave Ereignis tritt einmal auf.

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

Manipulationsereignisse

In Fällen, in denen eine Anwendung es einem Benutzer ermöglicht, ein Objekt zu bearbeiten, definiert die UIElement Klasse Manipulationsereignisse. Im Gegensatz zu den Touchereignissen, die einfach die Position der Toucheingabe melden, melden die Manipulationsereignisse, wie die Eingabe interpretiert werden kann. Es gibt drei Arten von Manipulationen: Verschiebungen, Erweiterungen und Drehungen. In der folgenden Liste wird beschrieben, wie die drei Arten von Manipulationen aufgerufen werden.

  • Setzen Sie einen Finger auf ein Objekt, und bewegen Sie den Finger über den Touchscreen, um eine Übersetzungsmanipulation aufzurufen. Dies verschiebt das Objekt in der Regel.

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

  • Setzen Sie zwei Finger auf ein Objekt, und drehen Sie die Finger umeinander, um eine Drehungsmanipulation aufzurufen. Dadurch wird das Objekt in der Regel gedreht.

Mehrere Manipulationsarten können gleichzeitig auftreten.

Wenn Sie bewirken, dass Objekte auf Manipulationen reagieren, können Sie sehen, dass das Objekt unträgheiten hat. Dies kann dazu führen, dass Ihre Objekte die physische Welt simulieren. Wenn Sie beispielsweise ein Buch über einen Tisch schieben und hart genug schieben, bewegt sich das Buch weiter, nachdem Sie es losgelassen haben. Mit WPF können Sie dieses Verhalten simulieren, indem Sie Manipulationsereignisse auslösen, nachdem die Finger des Benutzers das Objekt loslassen.

Informationen zum Erstellen einer Anwendung, die es dem Benutzer ermöglicht, ein Objekt zu verschieben, zu ändern und zu drehen, finden Sie unter Walkthrough: Creating Your First Touch Application.

Der UIElement definiert die folgenden Manipulationsereignisse.

Standardmäßig empfängt ein UIElement keine Manipulationsevents. Zum Empfangen von Manipulationsereignissen für ein UIElement, setzen Sie UIElement.IsManipulationEnabled auf true.

Der Ausführungspfad von Manipulationsereignissen

Betrachten Sie ein Szenario, in dem ein Benutzer ein Objekt wirft. Der Benutzer legt einen Finger auf das Objekt, bewegt den Finger über den Touchscreen für einen kurzen Abstand und hebt dann den Finger an, während er bewegt wird. Das Ergebnis ist, dass sich das Objekt unter dem Finger des Benutzers bewegt und weiter bewegt wird, nachdem der Benutzer den Finger anhebt.

Die folgende Abbildung zeigt den Ausführungspfad von Manipulationsereignissen und wichtige Informationen zu den einzelnen Ereignissen.

Die Abfolge von Manipulationsereignissen. Manipulationsereignisse

In der folgenden Liste wird die Abfolge der Ereignisse in der vorherigen Abbildung beschrieben.

  1. Das ManipulationStarting Ereignis tritt auf, wenn der Benutzer einen Finger auf das Objekt platziert. Unter anderem können Sie mit diesem Ereignis die ManipulationContainer Eigenschaft festlegen. In den nachfolgenden Ereignissen wird die Position der Manipulation relativ zu der ManipulationContainer. Außer bei ManipulationStarting-Ereignissen ist diese Eigenschaft schreibgeschützt, sodass das ManipulationStarting-Ereignis die einzige Gelegenheit darstellt, um diese Eigenschaft festzulegen.

  2. Das ManipulationStarted Ereignis tritt als nächstes ein. 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 Manipulation als Bewegung, Erweiterung oder Übersetzung interpretiert wird. Hier führen Sie den größten Teil der Bearbeitung eines Objekts durch.

  4. Das ManipulationInertiaStarting Ereignis tritt auf, wenn der Finger des Benutzers den Kontakt mit dem Objekt verliert. Mit diesem Ereignis können Sie die Verzögerung der Manipulationen während der Trägheit angeben. Dies ermöglicht es Ihrem Objekt, bei Bedarf verschiedene physische Räume oder Attribute zu emulieren. Angenommen, Ihre Anwendung verfügt über zwei Objekte, die Elemente in der physischen Welt darstellen, und eine ist schwerer als die andere. Sie können das schwerere Objekt schneller verlangsamen als das hellere Objekt.

  5. Das ManipulationDelta Ereignis tritt mehrmals auf, wenn die Unträgheit auftritt. Beachten Sie, dass dieses Ereignis auftritt, wenn sich die Finger des Benutzers über den Touchscreen bewegen und WPF Trägheit simuliert. Mit anderen Worten, ManipulationDelta tritt vor und nach dem ManipulationInertiaStarting Ereignis auf. Die ManipulationDeltaEventArgs.IsInertial Eigenschaft meldet, ob das Ereignis während der ManipulationDelta Unträgheit auftritt, sodass Sie diese Eigenschaft überprüfen und je nach Wert unterschiedliche Aktionen ausführen können.

  6. Das ManipulationCompleted Ereignis tritt auf, wenn die Manipulation und alle Inertiationen enden. Das heißt, nachdem alle ManipulationDelta Ereignisse aufgetreten sind, tritt das ManipulationCompleted Ereignis auf, um zu signalisieren, dass die Manipulation abgeschlossen ist.

Das 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, visuelles Feedback bereitzustellen, wenn ein Objekt auf eine Grenze trifft. Beispielsweise behandelt die Window Klasse das ManipulationBoundaryFeedback Ereignis, damit sich das Fenster leicht bewegt, wenn der Rand berührt wird.

Sie können die Bearbeitung abbrechen, indem Sie die Cancel Methode für die Ereignisargumente in jedem Manipulationsereignis außer ManipulationBoundaryFeedback ereignis aufrufen. Wenn Sie Cancel aufrufen, werden die Manipulationsereignisse nicht mehr ausgelöst, und stattdessen treten Mausereignisse für die Toucheingabe auf. Die folgende Tabelle beschreibt die Beziehung zwischen dem Zeitpunkt, zu dem die Manipulation abgebrochen wird, und den auftretenden Mausereignissen.

Das Ereignis, in dem Cancel aufgerufen wird Die Mausereignisse, die für bereits aufgetretene Eingaben auftreten
ManipulationStarting und ManipulationStarted Mousedown-Ereignisse.
ManipulationDelta Maus-nach-unten- und Mausbewegungsereignisse.
ManipulationInertiaStarting und ManipulationCompleted Maus-nach-unten-, Mausbewegungs- und Maus-up-Ereignisse.

Beachten Sie, dass, wenn die Manipulation in der Trägheitsphase ist und Cancel aufgerufen wird, die Methode false zurückgegeben wird und die Eingabe keine Mausereignisse auslöst.

Die Beziehung zwischen Touch- und Manipulationsereignissen

Ein UIElement kann immer Berührungsereignisse empfangen. Wenn die IsManipulationEnabled-Eigenschaft auf true festgelegt ist, kann UIElement sowohl Touch- als auch Manipulationsereignisse empfangen. Wenn das TouchDown Ereignis nicht behandelt wird (d. h. die Handled Eigenschaft ist false), erfasst die Manipulationslogik die Toucheingabe für das Element und generiert die Manipulationsereignisse. Wenn im Handled Ereignis die true Eigenschaft auf TouchDown festgelegt wird, generiert die Manipulationslogik keine Manipulationsereignisse. Die folgende Abbildung zeigt die Beziehung zwischen Touchereignissen und Manipulationsereignissen.

Beziehung zwischen Touch- und Manipulationsereignissen Touch- und Manipulationsereignisse

In der folgenden Liste wird die Beziehung zwischen den Touch- und Manipulationsereignissen beschrieben, die in der vorherigen Abbildung dargestellt werden.

Fokus

Es gibt zwei Hauptkonzepte für den Fokus in WPF: 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 vorhanden sein, das den Tastaturfokus besitzt. In WPF wird das Element, das den Tastaturfokus besitzt, auf IsKeyboardFocused gesetzt. Die statische Keyboard Methode FocusedElement gibt das Element zurück, das derzeit den Tastaturfokus besitzt.

Der Tastaturfokus kann durch Drücken der Tabulatortaste zu einem Element oder durch Klicken auf die Maus auf bestimmte Elemente wie z. B. ein TextBoxElement abgerufen werden. Der Tastaturfokus kann auch programmgesteuert mithilfe der Focus Methode für die Keyboard Klasse abgerufen werden. Focus versucht, dem angegebenen Element den Tastaturfokus zuzuweisen. Das Element, das von Focus zurückgegeben wird, ist das Element, das derzeit den Tastaturfokus hat.

Damit ein Element den Tastaturfokus erhält, muss die Focusable Eigenschaft und die IsVisible Eigenschaften auf "true" festgelegt werden. Einige Klassen, wie Panel, haben standardmäßig Focusable für false gesetzt. Daher müssen Sie möglicherweise diese Eigenschaft auf true festlegen, wenn Sie möchten, dass dieses Element den Fokus erhalten kann.

Im folgenden Beispiel wird mit Focus der Tastaturfokus auf ein Button gesetzt. Der empfohlene Ort zum Festlegen des anfänglichen Fokus in einer Anwendung befindet sich im Loaded Ereignishandler.

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 zum Tastaturfokus finden Sie unter "Fokusübersicht".

Logischer Fokus

Der logische Fokus bezieht sich auf den FocusManager.FocusedElement in einem Fokusbereich. Es können mehrere Elemente vorhanden sein, die den logischen Fokus in einer Anwendung haben, aber es kann nur ein Element geben, das den logischen Fokus in einem bestimmten Fokusbereich hat.

Ein Fokusbereich ist ein Containerelement, das den Überblick über den FocusedElement Bereich behält. Wenn der Fokus einen Fokusbereich verlässt, verliert das fokussierte Element den Tastaturfokus, behält aber den logischen Fokus bei. Wenn der Fokus zum Fokusbereich zurückkehrt, erhält das fokussierte Element den Tastaturfokus. Dadurch kann der Tastaturfokus zwischen mehreren Fokusbereichen geändert werden, stellt jedoch sicher, dass das fokussierte Element innerhalb des Fokusbereichs das fokussierte Element bleibt, wenn der Fokus zurückgegeben wird.

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

Im folgenden Beispiel wird ein StackPanel zu einem Fokusbereich, indem die angefügte Eigenschaft IsFocusScope 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, ToolBarund ContextMenu.

Ein Element mit Tastaturfokus hat auch den logischen Fokus für den Fokusbereich, zu dem es gehört; Daher wird das Festlegen des Fokus auf ein Element mit der Focus-Methode der Keyboard-Klasse oder der Basiselementklassen versuchen, dem Element sowohl Tastaturfokus als auch logischen Fokus zu geben.

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

Weitere Informationen zum logischen Fokus finden Sie unter "Fokusübersicht".

Mausposition

Die WPF-Eingabe-API bietet hilfreiche Informationen in Bezug auf Koordinatenräume. Die Koordinate (0,0) ist zum Beispiel die obere linke Koordinate, aber die obere linke Ecke welches Elements im Baum? Das Element, das als Eingabeziel dient? Das Element, dem Sie den Ereignishandler angehängt haben? Oder etwas anderes? Um Verwirrung zu vermeiden, erfordert die WPF-Eingabe-API, dass Sie den Referenzrahmen angeben, wenn Sie mit Koordinaten arbeiten, die über die Maus abgerufen wurden. Die GetPosition Methode gibt die Koordinate des Mauszeigers relativ zum angegebenen Element zurück.

Mausaufzeichnung

Mausgeräte enthalten speziell ein modales Merkmal, das als Mauserfassung bezeichnet wird. Die Mauserfassung wird verwendet, um einen Übergangseingabezustand beizubehalten, wenn ein Drag-and-Drop-Vorgang gestartet wird, sodass andere Vorgänge, die die nominale Bildschirmposition des Mauszeigers einbeziehen, nicht notwendigerweise auftreten. Während des Ziehens kann der Benutzer nicht klicken, ohne den Drag-and-Drop abzubrechen, was die meisten Mouseover-Hinweise unangemessen macht, solange die Maussteuerung vom Ziehursprung gehalten wird. Das Eingabesystem macht APIs verfügbar, die den Mausaufnahmezustand sowie APIs bestimmen können, die die Mausaufnahme zu einem bestimmten Element erzwingen oder den Mausaufnahmezustand löschen können. Weitere Informationen zu Drag-and-Drop-Vorgängen finden Sie unter "Drag and Drop Overview".

Befehle

Befehle ermöglichen die Eingabebehandlung auf semantischerer Ebene als Geräteeingaben. Befehle sind einfache Direktiven wie Cut, Copy, Paste oder Open. Befehle sind nützlich, um Ihre Befehlslogik zu zentralisieren. Auf denselben Befehl kann über ein Menu, ein ToolBar, oder eine Tastenkombination zugegriffen werden. Befehle bieten auch einen Mechanismus zum Deaktivieren von Steuerelementen, wenn der Befehl nicht verfügbar ist.

RoutedCommand ist die WPF-Implementierung von ICommand. Wenn ein RoutedCommand ausgeführt wird, werden ein PreviewExecuted Ereignis und ein Executed Ereignis auf dem Befehlsziel ausgelöst, die durch den Elementbaum tunneln und bubblen wie andere Eingaben. Wenn kein Befehlsziel festgelegt ist, ist das Element mit Tastaturfokus das Befehlsziel. Die Logik, die den Befehl ausführt, ist an ein CommandBinding angefügt. Wenn ein Executed-Ereignis einen CommandBinding für diesen bestimmten Befehl erreicht, wird das ExecutedRoutedEventHandler auf dem CommandBinding aufgerufen. Dieser Handler führt die Aktion des Befehls aus.

Weitere Informationen zum Befehlen finden Sie unter Commanding Overview.

WPF stellt eine Bibliothek mit allgemeinen Befehlen bereit, die aus ApplicationCommands, MediaCommands, ComponentCommands, NavigationCommands und EditingCommands besteht, oder Sie können eigene definieren.

Im folgenden Beispiel wird gezeigt, wie ein MenuItem eingerichtet wird, so dass beim Klicken darauf der Paste Befehl auf dem TextBox aufgerufen wird, vorausgesetzt, der TextBox den Tastaturfokus hat.

<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 unter Commanding Overview.

Eingabesystem und Basiselemente

Eingabeereignisse, wie die durch die Mouse, Keyboard und Stylus Klassen definierten angefügten Ereignisse, werden vom Eingabesystem ausgelöst und zur Laufzeit basierend auf Hit-Tests der visuellen Struktur in eine bestimmte Position im Objektmodell eingefügt.

Jedes Ereignis, das Mouse, Keyboard und Stylus als angefügtes Ereignis definiert wird, wird von den Basiselementklassen UIElement und ContentElement auch als ein neues geroutetes Ereignis wieder verfügbar gemacht. Die Routingereignisse des Basiselements werden von Klassen generiert, die das ursprüngliche angefügte Ereignis behandeln und die Ereignisdaten erneut verwenden.

Wenn das Eingabeereignis einem bestimmten Quellelement über die Implementierung des Basiselementeingabeereignisses zugeordnet wird, kann es über den Rest einer Ereignisroute geleitet werden, die auf einer Kombination aus logischen und visuellen Strukturobjekten basiert und von Anwendungscode behandelt wird. Im Allgemeinen ist es bequemer, diese gerätebezogenen Eingabeereignisse mithilfe der routeten Ereignisse auf UIElement und ContentElement zu behandeln, da Sie eine intuitivere Ereignishandlersyntax sowohl in XAML als auch im Code verwenden können. Sie könnten stattdessen das angehängte Ereignis behandeln, das den Prozess gestartet hat. Dabei würden jedoch mehrere Probleme auftreten: Das angefügte Ereignis könnte als behandelt markiert sein durch die Behandlung in der Basiselementklasse. Zudem müssen Sie Accessormethoden verwenden, anstelle der eigentlichen Ereignissyntax, um Handler für angefügte Ereignisse anzufügen.

Was kommt als nächstes

Sie verfügen jetzt über mehrere Techniken zum Behandeln von Eingaben in WPF. Außerdem sollten Sie ein besseres Verständnis der verschiedenen Arten von Eingabeereignissen und der von WPF verwendeten Routingereignismechanismen haben.

Weitere Ressourcen sind verfügbar, die WPF-Frameworkelemente und das Ereignisrouting ausführlicher erläutern. Weitere Informationen finden Sie in den folgenden Übersichten, Befehlsübersicht, Fokusübersicht, Übersicht über Basiselemente, Strukturen in WPF und Übersicht über Routingereignisse.

Siehe auch