Vue d'ensemble des entrées

Le sous-système WINDOWS Presentation Foundation (WPF) fournit une API puissante pour obtenir des entrées à partir d’un large éventail d’appareils, notamment la souris, le clavier, le toucher et le stylet. Cette rubrique décrit les services fournis par WPF et explique l’architecture des systèmes d’entrée.

API d’entrée

L’exposition de l’API d’entrée principale se trouve sur les classes d’éléments de base : UIElement, , ContentElementFrameworkElement, et FrameworkContentElement. Pour plus d’informations sur les éléments de base, consultez Vue d’ensemble des éléments de base. Ces classes fournissent la fonctionnalité pour les événements d’entrée associés aux appuis sur les boutons, aux boutons de la souris, à la roulette de la souris, au déplacement de la souris, à la gestion du focus et à la capture de la souris, entre autres. En plaçant l’API d’entrée sur les éléments de base, plutôt que de traiter tous les événements d’entrée en tant que service, l’architecture d’entrée permet aux événements d’entrée d’être sourcer par un objet particulier dans l’interface utilisateur et de prendre en charge un schéma de routage d’événements dans lequel plusieurs éléments ont la possibilité de gérer un événement d’entrée. De nombreux événements d’entrée sont associés à une paire d’événements. Par exemple, l’événement de mise hors clé est associé aux événements et PreviewKeyDown aux KeyDown événements. La différence entre ces événements réside dans la façon dont ils sont acheminés vers l’élément cible. Les événements Preview parcourent l’arborescence d’éléments de l’élément racine vers l’élément cible. Les événements de propagation se propagent de l’élément cible vers l’élément racine. Le routage des événements dans WPF est abordé plus en détail plus loin dans cette vue d’ensemble et dans la vue d’ensemble des événements routés.

Classes de souris et de clavier

Outre l’API d’entrée sur les classes d’éléments de base, la Keyboard classe et Mouse les classes fournissent une API supplémentaire pour l’utilisation d’une entrée clavier et souris.

Par exemple, l’API d’entrée sur la Keyboard classe est la Modifiers propriété, qui retourne la ModifierKeys valeur actuellement enfoncée et la IsKeyDown méthode, qui détermine si une touche spécifiée est enfoncée.

L’exemple suivant utilise la GetKeyStates méthode pour déterminer si un Key état est en panne.

// 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

Des exemples d’API d’entrée sur la Mouse classe sont MiddleButton, qui obtient l’état du bouton de la souris centrale et DirectlyOver, qui obtient l’élément sur lequel le pointeur de la souris est actuellement terminé.

L’exemple suivant détermine si la LeftButton souris est dans l’état Pressed .

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

Les Mouse classes et Keyboard les classes sont abordées plus en détail dans cette vue d’ensemble.

Entrée du stylet

WPF a intégré la prise en charge du Stylus. Il Stylus s’agit d’une entrée de stylet rendue populaire par le PC Tablette. Les applications WPF peuvent traiter le stylet comme une souris à l’aide de l’API de la souris, mais WPF expose également une abstraction d’appareil de stylet qui utilise un modèle similaire au clavier et à la souris. Toutes les API liées au stylet contiennent le mot « Stylet ».

Étant donné que le stylet peut agir comme une souris, les applications qui prennent uniquement en charge l’entrée de la souris peuvent quand même bénéficier automatiquement d’un certain niveau de prise en charge du stylet. Quand le stylet est utilisé de cette manière, l’application a la possibilité de gérer l’événement de stylet approprié, et elle gère ensuite l’événement de souris correspondant. En outre, les services de niveau supérieur tels que l’entrée d’encre sont également disponibles grâce à l’abstraction du stylet. Pour plus d’informations sur l’encre comme entrée, consultez Débuter avec l’encre.

Routage d’événements

Un FrameworkElement peut contenir d’autres éléments en tant qu’éléments enfants dans son con mode tente l, formant une arborescence d’éléments. Dans WPF, l’élément parent peut participer à l’entrée dirigée vers ses éléments enfants ou d’autres descendants en partageant des événements. Cela est particulièrement utile pour créer des contrôles à partir de contrôles plus petits, un processus appelé « composition de contrôle » ou « composition ». Pour plus d’informations sur les arborescences d’éléments et la façon dont les arborescences d’éléments se rapportent aux itinéraires d’événements, consultez Trees dans WPF.

Le routage d’événements est le processus qui consiste à transférer des événements à plusieurs éléments, afin qu’un objet ou un élément sur l’itinéraire puisse choisir de fournir une réponse significative (par l’intermédiaire de la gestion) à un événement ayant pu avoir comme source un autre élément. Les événements routés utilisent l’un des trois mécanismes de routage suivants : direct, par propagation et par tunneling. Avec le routage direct, l’élément source est le seul élément notifié, et l’événement n’est pas acheminé vers d’autres éléments. Toutefois, l’événement routé direct offre toujours certaines fonctionnalités supplémentaires qui sont uniquement présentes pour les événements routés par opposition aux événements CLR standard. La propagation remonte l’arborescence d’éléments en notifiant d’abord l’élément à l’origine de l’événement, puis l’élément parent, et ainsi de suite. Le tunneling commence à la racine de l’arborescence d’éléments puis descend, en finissant à l’élément source d’origine. Pour plus d’informations sur les événements routés, consultez Vue d’ensemble des événements routés.

Les événements d’entrée WPF sont généralement fournis en paires qui se composent d’un événement de tunneling et d’un événement de bulle. Les événements de tunneling se distinguent des événements de propagation par le préfixe « Preview ». Par exemple, PreviewMouseMove est la version de tunneling d’un événement de déplacement de la souris et MouseMove est la version de bubbling de cet événement. Ce jumelage d’événements est une convention implémentée au niveau de l’élément et qui n’est pas une fonctionnalité inhérente du système d’événements WPF. Pour plus d’informations, consultez la section Événements d’entrée WPF dans Vue d’ensemble des événements routés.

Gestion des événements d’entrée

Pour recevoir une entrée sur un élément, un gestionnaire d’événements doit être associé à cet événement particulier. En XAML, cela est simple : vous référencez le nom de l’événement en tant qu’attribut de l’élément qui sera à l’écoute de cet événement. Ensuite, vous affectez comme valeur de l’attribut le nom du gestionnaire d’événements que vous définissez, en fonction d’un délégué. Le gestionnaire d’événements doit être écrit dans du code tel que C# et peut être inclus dans un fichier code-behind.

Les événements de clavier se produisent quand le système d’exploitation signale des actions de touches qui ont lieu pendant que le focus clavier se trouve sur un élément. Les événements de souris et de stylet appartiennent chacun à deux catégories : les événements qui signalent des changements de la position du pointeur par rapport à l’élément, et les événements qui signalent des changements d’état des boutons du périphérique.

Exemple d’événement d’entrée de clavier

L’exemple suivant détecte un appui sur la touche de direction gauche. A StackPanel est créé avec un Button. Un gestionnaire d’événements pour écouter la touche de direction gauche est attaché à l’instance Button .

La première section de l’exemple crée et StackPanelButton attache le gestionnaire d’événements pour le KeyDown.

<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

La deuxième section est écrite en code et définit le gestionnaire d’événements. Lorsque la flèche gauche est enfoncée et que le Button focus clavier est activé, le gestionnaire s’exécute et la Background couleur du Button clavier est modifiée. Si la touche est enfoncée, mais qu’elle n’est pas la touche de direction gauche, la Background couleur du bouton Button est remplacée par sa couleur de départ.

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

Exemple d’événement d’entrée de souris

Dans l’exemple suivant, la Background couleur d’un est Button modifiée lorsque le pointeur de la souris entre dans le Button. La Background couleur est restaurée lorsque la souris quitte le Button.

La première section de l’exemple crée le contrôle et Button attache les gestionnaires d’événements pour les événements et MouseLeave les MouseEnter événements au Button.StackPanel

<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

La deuxième section est écrite en code et définit le gestionnaire d’événements. Lorsque la souris entre dans le Button, la Background couleur du fichier Button est remplacée SlateGraypar . Lorsque la souris quitte, Buttonla Background couleur du jeu Button est remplacée par AliceBlue.

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

Saisie de texte

L’événement TextInput vous permet d’écouter l’entrée de texte de manière indépendante de l’appareil. Le clavier est le principal moyen d’entrer du texte, mais la voix, l’écriture manuscrite et d’autres périphériques d’entrée peuvent aussi générer du texte.

Pour l’entrée au clavier, WPF envoie d’abord les événements appropriés KeyDown/KeyUp . Si ces événements ne sont pas gérés et que la clé est textuelle (plutôt qu’une touche de contrôle telle que des flèches directionnelles ou des touches de fonction), un TextInput événement est déclenché. Il n’existe pas toujours un mappage un-à-un simple entre KeyDown/KeyUp les TextInput événements, car plusieurs séquences de touches peuvent générer un seul caractère d’entrée de texte et des séquences de touches uniques peuvent générer des chaînes à caractères multiples. Cela est particulièrement vrai pour les langues telles que le chinois, le japonais et le coréen qui utilisent les éditeurs de méthode d’entrée (IMEs) pour générer les milliers de caractères possibles dans leurs alphabets correspondants.

Lorsque WPF envoie un KeyUp/KeyDown événement, Key est défini Key.System sur si les séquences de touches peuvent faire partie d’un TextInput événement (si ALT+S est appuyé, par exemple). Cela permet au code d’un gestionnaire d’événements KeyDown de case activée etKey.System, s’il est trouvé, de laisser le traitement pour le gestionnaire de l’événement déclenché TextInput par la suite. Dans ces cas, les différentes propriétés de l’argument TextCompositionEventArgs peuvent être utilisées pour déterminer les séquences de touches d’origine. De même, si un IME est actif, Key a la valeur , Key.ImeProcessedet ImeProcessedKey donne la séquence de touches ou les séquences de touches d’origine.

L’exemple suivant définit un gestionnaire pour l’événement Click et un gestionnaire pour l’événement KeyDown .

Le premier segment de code ou de balisage crée l’interface utilisateur.

<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

Le deuxième segment de code contient les gestionnaires d’événements.

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

Étant donné que les événements d’entrée bullent l’itinéraire des événements, l’entrée StackPanel reçoit l’entrée, quel que soit l’élément qui a le focus clavier. Le TextBox contrôle est averti en premier et le OnTextInputKeyDown gestionnaire est appelé uniquement si l’entrée TextBox n’a pas été gérée. Si l’événement PreviewKeyDown est utilisé au lieu de l’événement KeyDown , le OnTextInputKeyDown gestionnaire est appelé en premier.

Dans cet exemple, la logique de gestion est écrite deux fois : une fois pour Ctrl+O et une autre fois pour l’événement de clic du bouton. Vous pouvez simplifier cela en utilisant des commandes, au lieu de traiter les événements d’entrée directement. Les commandes sont traitées dans cet article et dans Vue d’ensemble des commandes.

Entrée tactile et manipulation

Du nouveau matériel et une nouvelle API dans le système d’exploitation Windows 7 permettent aux applications de recevoir une entrée à partir de plusieurs entrées tactiles simultanément. WPF permet aux applications de détecter et de répondre aux interactions tactiles de manière similaire à la réponse à d’autres entrées, telles que la souris ou le clavier, en déclenchant des événements lorsque l’interaction tactile se produit.

WPF expose deux types d’événements lorsque l’interaction tactile se produit : les événements tactiles et les événements de manipulation. Les événements tactiles fournissent des données brutes relatives à chaque doigt sur un écran tactile et à leur déplacement. Les événements de manipulation interprètent l’entrée comme des actions spécifiques. Les deux types d’événements sont présentés dans cette section.

Prérequis

Vous devez disposer des composants suivants pour développer une application qui répond aux entrées tactiles.

  • Visual Studio 2010.

  • Windows 7

  • Un appareil, tel qu’un écran tactile, qui prend en charge l’interface tactile Windows.

Terminologie

Les termes suivants sont utilisés quand l’entrée tactile est abordée.

  • L’entrée tactile est un type d’entrée d’utilisateur reconnu par Windows 7. En règle générale, l’entrée tactile est démarrée en plaçant des doigts sur un écran tactile. Notez que les appareils tels que les pavés tactiles qui sont courants sur les ordinateurs portables ne gèrent pas l’entrée tactile si l’appareil ne fait que convertir la position et le déplacement du doigt en tant qu’entrée de la souris.

  • L’interaction tactile multipoint est une entrée tactile qui se produit simultanément à partir de plusieurs points. Windows 7 et WPF prennent en charge multitouche. Chaque fois que l’interaction tactile est abordée dans la documentation de WPF, les concepts s’appliquent à multitouche.

  • Une manipulation se produit quand l’entrée tactile est interprétée comme une action physique appliquée à un objet. Dans WPF, les événements de manipulation interprètent l’entrée comme une manipulation de traduction, d’expansion ou de rotation.

  • Un touch device représente un périphérique qui génère une entrée tactile, par exemple un seul doigt sur un écran tactile.

Contrôles qui répondent aux entrées tactiles

Les contrôles suivants peuvent être parcourus en faisant glisser un doigt sur le contrôle, s’il a du contenu qui défile hors de l’affichage.

Définit ScrollViewer la propriété jointe qui vous permet de spécifier si le ScrollViewer.PanningMode mouvement panoramique tactile est activé horizontalement, verticalement, les deux ou aucun des deux. La ScrollViewer.PanningDeceleration propriété spécifie la vitesse à laquelle le défilement ralentit lorsque l’utilisateur lève le doigt à partir de l’écran tactile. La ScrollViewer.PanningRatio propriété jointe spécifie le ratio de décalage de défilement pour traduire le décalage de manipulation.

Événements tactiles

Les classes de base, , UIElement, UIElement3Det ContentElement, définissent des événements auxquels vous pouvez vous abonner afin que votre application réponde à l’interaction tactile. Les événements tactiles sont utiles quand votre application interprète l’entrée tactile comme autre chose que la manipulation d’un objet. Par exemple, une application qui permet à un utilisateur de dessiner avec un ou plusieurs doigts doit s’abonner aux événements tactiles.

Les trois classes définissent les événements suivants, qui se comportent de la même manière quelle que soit la classe de définition.

Comme les événements de clavier et de souris, les événements tactiles sont des événements routés. Les événements qui commencent par Preview sont des événements de tunneling et les événements qui commencent par Touch sont des événements de propagation. Pour plus d’informations sur les événements routés, consultez Vue d’ensemble des événements routés. Lorsque vous gérez ces événements, vous pouvez obtenir la position de l’entrée, par rapport à n’importe quel élément, en appelant la ou GetIntermediateTouchPoints la GetTouchPoint méthode.

Pour comprendre l’interaction entre les événements tactiles, considérez le scénario où un utilisateur place un doigt sur un élément, déplace son doigt dans l’élément, puis retire son doigt de l’élément. L’illustration suivante montre l’exécution des événements de propagation (les événements de tunneling sont omis par souci de simplicité).

The sequence of touch events. Événements tactiles

La liste suivante décrit la séquence des événements dans l’illustration précédente.

  1. L’événement TouchEnter se produit une fois lorsque l’utilisateur met un doigt sur l’élément.

  2. L’événement TouchDown se produit une seule fois.

  3. L’événement TouchMove se produit plusieurs fois lorsque l’utilisateur déplace le doigt dans l’élément.

  4. L’événement TouchUp se produit une fois lorsque l’utilisateur lève le doigt de l’élément.

  5. L’événement TouchLeave se produit une seule fois.

Quand plusieurs doigts sont utilisés, les événements se produisent pour chaque doigt.

Événements de manipulation

Dans les cas où une application permet à un utilisateur de manipuler un objet, la UIElement classe définit les événements de manipulation. Contrairement aux événements tactiles qui signalent simplement la position de l’entrée tactile, les événements de manipulation signalent comment l’entrée peut être interprétée. Il existe trois types de manipulations : translation, expansion et rotation. La liste suivante décrit comment appeler les trois types de manipulations.

  • Placez un doigt sur un objet et déplacez le doigt sur l’écran tactile pour appeler une manipulation de translation. Cela déplace habituellement l’objet.

  • Placez deux doigts sur un objet et rapprochez ou éloignez les doigts pour appeler une manipulation d’expansion. Cela redimensionne habituellement l’objet.

  • Placez deux doigts sur un objet et faites pivoter les doigts pour appeler une manipulation de rotation. Cela fait pivoter habituellement l’objet.

Plusieurs types de manipulations peuvent se produire simultanément.

Quand vous faites en sorte que des objets répondent à des manipulations, vous pouvez donner à l’objet une apparence d’inertie. Ainsi, vos objets peuvent simuler le monde physique. Par exemple, quand vous poussez un livre sur une table, si vous le poussez assez fort il continuera à se déplacer une fois que vous l’aurez relâché. WPF vous permet de simuler ce comportement en activant des événements de manipulation après que les doigts de l’utilisateur relâchent l’objet.

Pour plus d’informations sur la façon de créer une application qui permet à l’utilisateur de déplacer, de redimensionner et de faire pivoter un objet, consultez Procédure pas à pas : création de votre première application Touch.

Définit UIElement les événements de manipulation suivants.

Par défaut, a UIElement ne reçoit pas ces événements de manipulation. Pour recevoir des événements de manipulation sur un UIElement, défini UIElement.IsManipulationEnabled sur true.

Chemin d’exécution des événements de manipulation

Imaginez un scénario où un utilisateur « jette » un objet. L’utilisateur place un doigt sur l’objet, déplace son doigt sur l’écran tactile sur une courte distance, puis retire son doigt pendant qu’il le déplace. La conséquence est que l’objet se déplace sous le doigt de l’utilisateur et continue à se déplacer après que l’utilisateur a retiré son doigt.

L’illustration suivante montre le chemin d’exécution des événements de manipulation et des informations importantes sur chaque événement.

The sequence of manipulation events. Événements de manipulation

La liste suivante décrit la séquence des événements dans l’illustration précédente.

  1. L’événement ManipulationStarting se produit lorsque l’utilisateur place un doigt sur l’objet. Entre autres choses, cet événement vous permet de définir la ManipulationContainer propriété. Dans les événements suivants, la position de la manipulation sera relative au ManipulationContainer. Dans les événements autres que ManipulationStarting, cette propriété est en lecture seule. L’événement ManipulationStarting est donc la seule fois que vous pouvez définir cette propriété.

  2. L’événement ManipulationStarted se produit ensuite. Cet événement signale l’origine de la manipulation.

  3. L’événement ManipulationDelta se produit plusieurs fois lorsque les doigts d’un utilisateur se déplacent sur un écran tactile. La DeltaManipulation propriété de la ManipulationDeltaEventArgs classe indique si la manipulation est interprétée comme un mouvement, une expansion ou une traduction. C’est là que vous effectuez la plupart du travail de manipulation d’un objet.

  4. L’événement ManipulationInertiaStarting se produit lorsque les doigts de l’utilisateur perdent contact avec l’objet. Cet événement vous permet de spécifier la décélération des manipulations pendant l’inertie, ceci afin que votre objet puisse émuler différents attributs ou espaces physiques si vous le souhaitez. Par exemple, supposez que votre application a deux objets qui représentent des éléments dans le monde physique, et que l’un d’eux a un poids supérieur à l’autre. Vous pouvez faire en sorte que l’objet le plus lourd décélère plus rapidement que l’objet plus léger.

  5. L’événement ManipulationDelta se produit plusieurs fois au fur et à mesure que l’inertie se produit. Notez que cet événement se produit lorsque les doigts de l’utilisateur se déplacent sur l’écran tactile et lorsque WPF simule l’inertie. En d’autres termes, ManipulationDelta se produit avant et après l’événement ManipulationInertiaStarting . La ManipulationDeltaEventArgs.IsInertial propriété indique si l’événement ManipulationDelta se produit pendant l’inertie, de sorte que vous pouvez case activée cette propriété et effectuer différentes actions, en fonction de sa valeur.

  6. L’événement ManipulationCompleted se produit lorsque la manipulation et toute inertie se termine. Autrement dit, une fois que tous les ManipulationDelta événements se produisent, l’événement ManipulationCompleted se produit pour signaler que la manipulation est terminée.

Définit UIElement également l’événement ManipulationBoundaryFeedback . Cet événement se produit lorsque la ReportBoundaryFeedback méthode est appelée dans l’événement ManipulationDelta . L’événement ManipulationBoundaryFeedback permet aux applications ou aux composants de fournir des commentaires visuels lorsqu’un objet atteint une limite. Par exemple, la Window classe gère l’événement ManipulationBoundaryFeedback pour que la fenêtre se déplace légèrement lorsque son bord est rencontré.

Vous pouvez annuler la manipulation en appelant la Cancel méthode sur les arguments d’événement dans n’importe quel événement de manipulation, à l’exception ManipulationBoundaryFeedback de l’événement. Lorsque vous appelez Cancel, les événements de manipulation ne sont plus déclenchés et les événements de souris se produisent pour l’interaction tactile. Le tableau suivant décrit la relation entre le moment où la manipulation est annulée et les événements de souris qui se produisent.

Événement pendant lequel Cancel est appelé Événements de souris qui se produisent pour une entrée qui a déjà eu lieu
ManipulationStarting et ManipulationStarted Événements mouse down.
ManipulationDelta Événements mouse down et mouse move.
ManipulationInertiaStarting et ManipulationCompleted Événements mouse down, mouse move et mouse up.

Notez que si vous appelez Cancel lorsque la manipulation est en inertie, la méthode retourne false et l’entrée ne déclenche pas d’événements de souris.

Relation entre les événements tactiles et les événements de manipulation

Un UIElement peut toujours recevoir des événements tactiles. Lorsque la propriété est définie truesur , un UIElement objet peut recevoir à la IsManipulationEnabled fois des événements tactiles et de manipulation. Si l’événement TouchDown n’est pas géré (autrement dit, la propriété estfalse), la Handled logique de manipulation capture l’interaction tactile de l’élément et génère les événements de manipulation. Si la Handled propriété est définie true dans l’événement TouchDown , la logique de manipulation ne génère pas d’événements de manipulation. L’illustration suivante montre la relation entre les événements tactiles et les événements de manipulation.

Relationship between touch and manipulation events Événements tactiles et de manipulation

La liste suivante décrit la relation entre les événements tactiles et les événements de manipulation indiquée dans l’illustration précédente.

Focus

Il existe deux concepts principaux relatifs au focus dans WPF : le focus clavier et le focus logique.

Focus clavier

Le focus clavier fait référence à l’élément qui reçoit actuellement l’entrée au clavier. Un seul élément de l’ordinateur peut avoir le focus clavier. Dans WPF, l’élément qui a le focus clavier a IsKeyboardFocused la valeur true. La méthode FocusedElement statique Keyboard retourne l’élément qui a actuellement le focus clavier.

Le focus clavier peut être obtenu en tablant sur un élément ou en cliquant sur la souris sur certains éléments, tels qu’un TextBox. Le focus clavier peut également être obtenu par programmation à l’aide de la Focus méthode sur la Keyboard classe. Focus tente d’accorder le focus clavier de l’élément spécifié. L’élément retourné par Focus est l’élément qui a actuellement le focus clavier.

Pour qu’un élément obtienne le focus clavier sur la Focusable propriété et que les IsVisible propriétés doivent être définies sur true. Certaines classes, telles que Panel, ont Focusable la valeur false par défaut . Par conséquent, vous devrez peut-être définir cette propriété true si vous souhaitez que cet élément puisse obtenir le focus.

L’exemple suivant utilise Focus pour définir le focus clavier sur un Button. L’emplacement recommandé pour définir le focus initial dans une application se trouve dans le Loaded gestionnaire d’événements.

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

Pour plus d’informations sur le focus clavier, consultez Vue d’ensemble du focus.

Focus logique

Le focus logique fait référence à l’étendue FocusManager.FocusedElement d’un focus. Plusieurs éléments d’une application peuvent avoir le focus logique, mais un seul élément peut avoir le focus logique dans une portée de focus donnée.

Une étendue de focus est un élément conteneur qui effectue le suivi de l’étendue FocusedElement . Quand le focus quitte une portée de focus, l’élément ayant le focus perd le focus clavier, mais conserve le focus logique. Quand le focus revient dans la portée de focus, l’élément ayant le focus obtient le focus clavier. Cela permet au focus clavier de changer entre des portées de focus, et de s’assurer que l’élément ayant le focus dans la portée de focus demeure l’élément ayant le focus quand le focus revient.

Un élément peut être transformé en une étendue de focus dans XAML (Extensible Application Markup Language) en définissant la FocusManager propriété IsFocusScopetruejointe sur , ou dans le code en définissant la propriété jointe à l’aide de la SetIsFocusScope méthode.

L’exemple suivant transforme une StackPanel étendue de focus en définissant la IsFocusScope propriété jointe.

<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)

Les classes dans WPF qui sont des étendues de focus par défaut sont Window, Menu, ToolBaret ContextMenu.

Un élément qui a le focus clavier aura également le focus logique pour l’étendue du focus auquel il appartient ; par conséquent, la définition du focus sur un élément avec la Focus méthode sur la Keyboard classe ou les classes d’éléments de base tente de donner le focus clavier de l’élément et le focus logique.

Pour déterminer l’élément ciblé dans une étendue de focus, utilisez GetFocusedElement. Pour modifier l’élément prioritaire pour une étendue de focus, utilisez SetFocusedElement.

Pour plus d’informations sur le focus logique, consultez Vue d’ensemble du focus.

Position de la souris

L’API d’entrée WPF fournit des informations utiles concernant les espaces de coordonnées. Par exemple, la coordonnée (0,0) est la coordonnée de l’angle supérieur gauche, mais de quel élément dans l’arborescence ? L’élément qui est la cible d’entrée ? L’élément auquel vous avez attaché votre gestionnaire d’événements ? Ou un autre élément ? Pour éviter toute confusion, l’API d’entrée WPF nécessite que vous spécifiiez votre cadre de référence lorsque vous travaillez avec des coordonnées obtenues via la souris. La GetPosition méthode retourne la coordonnée du pointeur de la souris par rapport à l’élément spécifié.

Capture de la souris

Les souris ont une caractéristique modale spécifique appelée capture de la souris. La capture de la souris sert à tenir à jour un état d’entrée transitionnel quand une opération de glisser-déplacer commence, afin que les autres opérations impliquant la position nominale à l’écran du pointeur de la souris ne se produisent pas nécessairement. Pendant l’opération glisser, l’utilisateur ne peut pas cliquer sans annuler le glisser-déplacer, ce qui rend la plupart des indices de survol de souris inappropriés pendant que la capture de la souris est détenue par l’origine de l’opération glisser. Le système d’entrée expose les API qui peuvent déterminer l’état de capture de la souris, ainsi que les API qui peuvent forcer la capture de la souris à un élément spécifique ou effacer l’état de capture de la souris. Pour plus d’informations sur les opérations de glisser-déplacer, consultez Vue d’ensemble du glisser-déplacer.

Commandes

Les commandes permettent de gérer les entrées à un niveau plus sémantique que l’entrée de périphérique. Les commandes sont des directives simples, telles que Cut, Copy, Paste ou Open. Elles sont utiles pour centraliser la logique de commande. La même commande peut être accessible à partir d’un Menu, sur un ToolBarou via un raccourci clavier. Les commandes fournissent également un mécanisme permettant de désactiver des contrôles quand la commande devient indisponible.

RoutedCommand est l’implémentation WPF de ICommand. Lorsqu’un RoutedCommand événement est exécuté, un événement et un PreviewExecutedExecuted événement sont déclenchés sur la cible de commande, ce qui tunnel et bulle dans l’arborescence d’éléments comme d’autres entrées. Si une cible de commande n’est pas définie, l’élément qui a le focus clavier est la cible de commande. La logique qui exécute la commande est attachée à un CommandBinding. Lorsqu’un Executed événement atteint une CommandBinding commande spécifique, il ExecutedRoutedEventHandlerCommandBinding est appelé. Ce gestionnaire exécute l’action de la commande.

Pour plus d’informations sur l’exécution des commandes, consultez Vue d’ensemble des commandes.

WPF fournit une bibliothèque de commandes courantes qui se composent de ApplicationCommands, , MediaCommandsComponentCommands, NavigationCommandset , et EditingCommands, ou vous pouvez définir vos propres.

L’exemple suivant montre comment configurer un MenuItem élément de sorte qu’en cliquant dessus, il appelle la Paste commande sur le TextBox, en supposant que le TextBox focus clavier est activé.

<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

Pour plus d’informations sur les commandes dans WPF, consultez Vue d’ensemble des commandes.

Le système d’entrée et les éléments de base

Les événements d’entrée tels que les événements joints définis par le Mouse, Keyboardet Stylus les classes sont déclenchés par le système d’entrée et injectés dans une position particulière dans le modèle objet en fonction du test de positionnement de l’arborescence visuelle au moment de l’exécution.

Chacun des événements qui Mouse, Keyboardet Stylus définis en tant qu’événement attaché, est également re-exposé par les classes UIElement d’éléments de base et ContentElement en tant qu’événement routé. Les événements routés d’éléments de base sont générés par des classes gérant l’événement attaché d’origine et réutilisant les données d’événements.

Quand l’événement d’entrée est associé à un élément source particulier par l’intermédiaire de son implémentation d’événement d’entrée d’élément de base, il peut être routé le long du reste d’un itinéraire d’événement qui est basé sur une combinaison d’objets des arborescences visuelle et logique, et être géré par le code de l’application. En règle générale, il est plus pratique de gérer ces événements d’entrée liés à l’appareil à l’aide des événements routés et UIElementContentElement, car vous pouvez utiliser une syntaxe de gestionnaire d’événements plus intuitive à la fois en XAML et en code. Vous pouvez choisir à la place de gérer l’événement attaché qui a démarré le processus, mais vous serez alors confronté à plusieurs problèmes : l’événement attaché pourra être marqué comme géré par la gestion de classe d’élément de base, et vous devrez utiliser des méthodes d’accesseur plutôt qu’une réelle syntaxe d’événement pour attacher des gestionnaires pour les événements attachés.

Quelle est la prochaine étape ?

Vous avez maintenant plusieurs techniques pour gérer les entrées dans WPF. Vous devez également avoir une meilleure compréhension des différents types d’événements d’entrée et des mécanismes d’événements routés utilisés par WPF.

Des ressources supplémentaires sont disponibles pour expliquer plus en détail les éléments de l’infrastructure WPF et le routage des événements. Pour plus d’informations, consultez les vues d’ensemble suivantes : Vue d’ensemble des commandes, Vue d’ensemble du focus, Vue d’ensemble des éléments de base, Arborescences dans WPF et Vue d’ensemble des événements routés.

Voir aussi