Vue d’ensemble des événements et des événements routés

API importantes

Nous décrivons le concept de programmation des événements dans une application Windows Runtime, quand vous utilisez C#, Visual Basic ou les extensions de composants Visual C++ (C++/CX) comme langage de programmation et le langage XAML pour la définition de votre IU. Vous pouvez assigner des gestionnaires pour les événements dans le cadre des déclarations des éléments d’interface utilisateur en XAML, ou vous pouvez ajouter les gestionnaires dans le code. Windows Runtime prend en charge les événements routés : certains événements d’entrée et événements de données peuvent être gérés par des objets autres que l’objet ayant déclenché l’événement. Les événements routés s’avèrent utiles quand vous définissez des modèles de contrôles ou utilisez des pages ou conteneurs de disposition.

Événements en tant que concept de programmation

En règle générale, les concepts d’événement lors de la programmation d’une application Windows Runtime sont similaires au modèle d’événement dans les langages de programmation les plus populaires. Si vous savez comment utiliser des événements Microsoft .NET ou C++ déjà, vous avez un point de départ. Mais vous n’avez pas besoin de savoir que beaucoup sur les concepts du modèle d’événement pour effectuer certaines tâches de base, telles que l’attachement de gestionnaires.

Lorsque vous utilisez C#, Visual Basic ou C++/CX comme langage de programmation, l’IU est définie dans la balise (XAML). Dans la syntaxe de balisage XAML, certains des principes de connexion d’événements entre les éléments de balisage et les entités de code d’exécution sont similaires à d’autres technologies Web, telles que ASP.NET ou HTML5.

Notez que le code qui fournit la logique d’exécution d’une IU définie par XAML est souvent appelé code-behind ou fichier code-behind. Dans les vues de solution Microsoft Visual Studio, cette relation s’affiche graphiquement, avec le fichier code-behind étant un fichier dépendant et imbriqué par rapport à la page XAML à laquelle il fait référence.

Button.Click : présentation des événements et XAML

L’une des tâches de programmation les plus courantes pour une application Windows Runtime consiste à capturer l’entrée utilisateur dans l’interface utilisateur. Par exemple, votre IU peut avoir un bouton que l’utilisateur doit cliquer pour envoyer des informations ou modifier l’état.

Vous définissez l’interface utilisateur de votre application Windows Runtime en générant XAML. Ce code XAML est généralement la sortie d’une surface de conception dans Visual Studio. Vous pouvez également écrire le code XAML dans un éditeur de texte brut ou un éditeur XAML tiers. Lors de la génération de ce code XAML, vous pouvez lier des gestionnaires d’événements pour des éléments d’IU individuels en même temps que vous définissez tous les autres attributs XAML qui établissent des valeurs de propriété de cet élément d’IU.

Pour connecter les événements en XAML, vous spécifiez le nom de formulaire de chaîne de la méthode de gestionnaire que vous avez déjà définie ou que vous définirez ultérieurement dans votre code-behind. Par exemple, ce code XAML définit un objet Button avec d’autres propriétés (attribut x:Name, Content) attribuées en tant qu’attributs et relie un gestionnaire pour l’événement Click du bouton en référençant une méthode nommée ShowUpdatesButton_Click :

<Button x:Name="showUpdatesButton"
  Content="{Binding ShowUpdatesText}"
  Click="ShowUpdatesButton_Click"/>

AstuceCâblage d’événement est un terme de programmation. Il fait référence au processus ou au code dans lequel vous indiquez que les occurrences d’un événement doivent appeler une méthode de gestionnaire nommée. Dans la plupart des modèles de code procédural, le câblage d’événements est un code « AddHandler » implicite ou explicite qui nomme à la fois l’événement et la méthode, et implique généralement une instance d’objet cible. En XAML, « AddHandler » est implicite et le câblage des événements consiste entièrement à nommer l’événement comme nom d’attribut d’un élément objet et à nommer le gestionnaire comme valeur de cet attribut.

Vous écrivez le gestionnaire réel dans le langage de programmation que vous utilisez pour tout le code et le code-behind de votre application. Avec l’attribut Click="ShowUpdatesButton_Click", vous avez créé un contrat qui, lorsque le code XAML est compilé et analysé, à la fois l’étape de compilation de balisage XAML dans l’action de génération de votre IDE et l’analyse XAML éventuelle lorsque l’application se charge peut trouver une méthode nommée ShowUpdatesButton_Click dans le code de l’application. ShowUpdatesButton_Click doit être une méthode qui implémente une signature de méthode compatible (basée sur un délégué) pour tout gestionnaire de l’événement Click . Par exemple, ce code définit le gestionnaire ShowUpdatesButton_Click.

private void ShowUpdatesButton_Click (object sender, RoutedEventArgs e) 
{
    Button b = sender as Button;
    //more logic to do here...
}
Private Sub ShowUpdatesButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim b As Button = CType(sender, Button)
    '  more logic to do here...
End Sub
void winrt::MyNamespace::implementation::BlankPage::ShowUpdatesButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e)
{
    auto b{ sender.as<Windows::UI::Xaml::Controls::Button>() };
    // More logic to do here.
}
void MyNamespace::BlankPage::ShowUpdatesButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) 
{
    Button^ b = (Button^) sender;
    //more logic to do here...
}

Dans cet exemple, la méthode ShowUpdatesButton_Click est basée sur le délégué RoutedEventHandler. Vous savez qu’il s’agit du délégué à utiliser, car vous verrez ce délégué nommé dans la syntaxe de la méthode Click.

Conseil Visual Studio fournit un moyen pratique de nommer le gestionnaire d’événements et de définir la méthode de gestionnaire pendant que vous modifiez XAML. Lorsque vous fournissez le nom d’attribut de l’événement dans l’éditeur de texte XAML, patientez un instant jusqu’à ce qu’une liste Microsoft IntelliSense s’affiche. Si vous cliquez sur <Nouveau gestionnaire d’événements >dans la liste, Microsoft Visual Studio suggère un nom de méthode en fonction du nom x:Name de l’élément (ou nom de type), du nom de l’événement et d’un suffixe numérique. Vous pouvez ensuite cliquer avec le bouton droit sur le nom du gestionnaire d’événements sélectionné, puis cliquer sur Naviguer vers le gestionnaire d’événements. Vous accédez directement à la définition du gestionnaire d’événements nouvellement inséré, comme indiqué dans la vue de l’éditeur de code de votre fichier code-behind pour la page XAML. Le gestionnaire d’événements a déjà la signature correcte, y compris le paramètre d’expéditeur et la classe de données d’événement utilisée par l’événement. De plus, si une méthode de gestionnaire avec la signature correcte existe déjà dans votre code-behind, le nom de cette méthode apparaît dans la liste déroulante de saisie semi-automatique, ainsi que l’option <Nouveau gestionnaire d’événements>. Vous pouvez également appuyer sur la touche TAB en tant que raccourci au lieu de cliquer sur les éléments de liste IntelliSense.

Définition d’un gestionnaires d'événements

Pour les objets qui sont des éléments d’IU et déclarés en XAML, le code du gestionnaire d’événements est défini dans la classe partielle qui sert de code-behind pour une page XAML. Les gestionnaires d’événements sont des méthodes que vous écrivez dans le cadre de la classe partielle associée à votre code XAML. Ces gestionnaires d’événements sont basés sur les délégués qu’un événement particulier utilise. Vos méthodes de gestionnaire d’événements peuvent être publiques ou privées. L’accès privé fonctionne, car le gestionnaire et l’instance créés par le code XAML sont finalement joints par la génération de code. En général, nous vous recommandons de rendre vos méthodes de gestionnaire d’événements privées dans la classe.

Notez que les gestionnaires d’événements pour C++ ne sont pas définis dans les classes partielles, ils sont déclarés dans l’en-tête en tant que membre de classe privé. Les actions de génération d’un projet C++ prennent en charge la génération de code qui prend en charge le système de type XAML et le modèle code-behind pour C++.

Paramètres de l’expéditeur et données d’événement

Le gestionnaire que vous écrivez pour l’événement peut accéder à deux valeurs disponibles comme entrée pour chaque cas où votre gestionnaire est appelé. Le premier est expéditeur qui est une référence à l’objet auquel le gestionnaire est attaché. Le paramètre expéditeur est typé comme type d’objet de base. Une technique courante consiste à convertir l’expéditeur en un type plus précis. Cette technique est utile si vous vous attendez à vérifier ou à modifier l’état sur l’objet expéditeur lui-même. En fonction de la conception de votre propre application, vous connaissez généralement un type vers lequel un transtypage de sender peut être effectué en toute sécurité, selon l’élément auquel le gestionnaire est attaché ou d’autres spécificités de la conception.

La seconde valeur correspond aux données d’événement, qui apparaissent généralement dans les définitions de syntaxe sous la forme du paramètre e. Vous pouvez découvrir les propriétés des données d’événement disponibles en examinant le paramètre e du délégué attribué à l’événement spécifique que vous gérez, puis en utilisant IntelliSense ou Object Browser dans Visual Studio. Vous pouvez également utiliser la documentation de référence Windows Runtime.

Pour certains événements, les valeurs de propriété spécifiques des données d’événement sont aussi importantes que de savoir que l’événement s’est produit. Cela est particulièrement vrai pour les événements d’entrée. Pour les événements de pointeur, la position du pointeur lorsque l’événement s’est produit peut être importante. Pour les événements clavier, toutes les touches possibles appuient sur un événement KeyDown et KeyUp. Pour déterminer la touche enfoncée par un utilisateur, vous devez accéder à KeyRoutedEventArgs disponible pour le gestionnaire d’événements. Pour plus d’informations sur la gestion des événements d’entrée, consultez Interactions clavier et Gérer les entrées de pointeur. Les événements d’entrée et les scénarios d’entrée ont souvent des considérations supplémentaires qui ne sont pas abordées dans cette rubrique, telles que la capture de pointeur pour les événements de pointeur, les touches de modification et les codes de touche de plateforme pour les événements de clavier.

Gestionnaires d’événements qui utilisent le modèle asynchrone

Dans certains cas, vous souhaiterez utiliser des API qui utilisent un modèle asynchrone au sein d’un gestionnaire d’événements. Par exemple, vous pouvez utiliser un bouton dans une barre d’applications pour afficher un sélecteur de fichiers et interagir avec celui-ci. Toutefois, la plupart des API du sélecteur de fichiers sont asynchrones. Ils doivent être appelés dans une étendue asynchrone/attendue, et le compilateur applique cela. Par conséquent, vous pouvez ajouter le mot clé async à votre gestionnaire d’événements afin que le gestionnaire soit désormais asyncvoid. À présent, votre gestionnaire d’événements est autorisé à effectuer des appels asynchrones/awaitables.

Pour obtenir un exemple de gestion des événements d’interaction utilisateur à l’aide du modèle asynchrone, consultez l’accès aux fichiers et les sélecteurs (dans le cadre de la création de votre première application Windows Runtime à l’aide de C# ou de la série Visual Basic). Consultez également [Appeler des API asynchrones en C).

Ajout de gestionnaires d’événements dans le code

XAML n’est pas la seule façon d’attribuer un gestionnaire d’événements à un objet. Pour ajouter des gestionnaires d’événements à n’importe quel objet donné dans le code, y compris aux objets qui ne sont pas utilisables en XAML, vous pouvez utiliser la syntaxe spécifique au langage pour ajouter des gestionnaires d’événements.

En C#, la syntaxe consiste à utiliser l’opérateur +=. Vous inscrivez le gestionnaire en référençant le nom de la méthode du gestionnaire d’événements sur le côté droit de l’opérateur.

Si vous utilisez du code pour ajouter des gestionnaires d’événements à des objets qui apparaissent dans l’interface utilisateur d’exécution, une pratique courante consiste à ajouter de tels gestionnaires en réponse à un événement de durée de vie d’objet ou un rappel, tel que Loaded ou OnApplyTemplate, afin que les gestionnaires d’événements sur l’objet approprié soient prêts pour les événements initiés par l’utilisateur à l’exécution. Cet exemple montre un plan XAML de la structure de page, puis fournit la syntaxe du langage C# pour ajouter un gestionnaire d’événements à un objet.

<Grid x:Name="LayoutRoot" Loaded="LayoutRoot_Loaded">
  <StackPanel>
    <TextBlock Name="textBlock1">Put the pointer over this text</TextBlock>
...
  </StackPanel>
</Grid>
void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    textBlock1.PointerEntered += textBlock1_PointerEntered;
    textBlock1.PointerExited += textBlock1_PointerExited;
}

Notez qu’il existe une syntaxe plus détaillée. En 2005, C# a ajouté une fonctionnalité appelée inférence de délégué, qui permet à un compilateur de déduire la nouvelle instance de délégué et d’activer la syntaxe précédente, plus simple. La syntaxe détaillée est fonctionnellement identique à l’exemple précédent, mais crée explicitement une instance de délégué avant de l’inscrire, ce qui ne tire pas parti de l’inférence de délégué. Cette syntaxe explicite est moins courante, mais vous pouvez toujours la voir dans certains exemples de code.

void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    textBlock1.PointerEntered += new PointerEventHandler(textBlock1_PointerEntered);
    textBlock1.PointerExited += new MouseEventHandler(textBlock1_PointerExited);
}

Il existe deux possibilités pour la syntaxe Visual Basic. Il s’agit de mettre en parallèle la syntaxe C# et d’attacher des gestionnaires directement aux instances. Cela nécessite le mot clé AddHandler et l’opérateur AddressOf qui déréférencent le nom de la méthode du gestionnaire.

L’autre option de la syntaxe Visual Basic consiste à utiliser le mot clé Handles sur les gestionnaires d’événements. Cette technique est appropriée pour les cas où les gestionnaires sont censés exister sur des objets au moment du chargement et conserver tout au long de la durée de vie de l’objet. L’utilisation de Handles sur un objet défini en XAML nécessite que vous fournissez un nom / x:Name. Ce nom devient le qualificateur d’instance nécessaire pour la partie Instance.Event de la syntaxe Handles. Dans ce cas, vous n’avez pas besoin d’un gestionnaire d’événements basé sur la durée de vie de l’objet pour lancer l’attachement des autres gestionnaires d’événements ; les connexions Handles sont créées lorsque vous compilez votre page XAML.

Private Sub textBlock1_PointerEntered(ByVal sender As Object, ByVal e As PointerRoutedEventArgs) Handles textBlock1.PointerEntered
' ...
End Sub

Notez que Visual Studio et son aire de conception XAML favorisent généralement la technique de gestion des instances au lieu du mot clé Handles. Cela est dû au fait que l’établissement du câblage du gestionnaire d’événements en XAML fait partie du flux de travail concepteur-développeur générale, et que la technique du mot clé handles est incompatible avec le câblage des gestionnaires d’événements en XAML.

En C++/CX, vous utilisez également la syntaxe +=, mais il existe des différences par rapport au formulaire C# de base :

  • Aucune inférence de délégué n’existe. Vous devez donc utiliser la référence nouvelle pour l’instance de délégué.
  • Le constructeur délégué a deux paramètres et requiert l’objet cible comme premier paramètre. En règle générale, vous spécifiez ceci.
  • Le constructeur délégué requiert l’adresse de la méthode en tant que deuxième paramètre. L’opérateur de référence & précède donc le nom de la méthode.
textBlock1().PointerEntered({this, &MainPage::TextBlock1_PointerEntered });
textBlock1->PointerEntered += 
ref new PointerEventHandler(this, &BlankPage::textBlock1_PointerEntered);

Suppression de gestionnaires d’événements dans le code

Il n’est généralement pas nécessaire de supprimer des gestionnaires d’événements dans le code, même si vous les avez ajoutés dans le code. Le comportement de durée de vie des objets Windows Runtime pour la plupart des objets Windows Runtime, tels que les pages et les contrôles, détruit les objets lorsqu’ils sont déconnectés de la fenêtre principale et de son arborescence visuelle, et toutes les références de délégué sont également détruites. .NET effectue cette opération via le garbage collection et Windows Runtime avec C++/CX utilise des références faibles par défaut.

Il existe quelques rares cas où vous souhaitez supprimer explicitement des gestionnaires d’événements. Il s’agit notamment des paramètres suivants :

  • Les gestionnaires que vous avez ajoutés pour les événements statiques, qui ne peuvent pas passer par le garbage collector de manière conventionnelle. Des exemples d’événements statiques dans l’API Windows Runtime sont les événements des classes CompositionTarget et Presse-papiers.
  • Testez le code dans lequel vous souhaitez que le minutage de la suppression du gestionnaire soit immédiat, ou le code dans lequel vous souhaitez échanger des gestionnaires d’événements anciens/nouveaux pour un événement au moment de l’exécution.
  • Implémentation d’un accesseur de suppression personnalisé.
  • Événements statiques personnalisés.
  • Gestionnaires pour les navigations de page.

FrameworkElement.Unloaded ou Page.NavigatedFrom sont des déclencheurs d’événements possibles qui ont des positions appropriées dans la gestion de l’état et la durée de vie de l’objet afin que vous puissiez les utiliser pour supprimer des gestionnaires pour d’autres événements.

Par exemple, vous pouvez supprimer un gestionnaire d’événements nommé textBlock1_PointerEntered de l’objet cible textBlock1 à l’aide de ce code.

textBlock1.PointerEntered -= textBlock1_PointerEntered;
RemoveHandler textBlock1.PointerEntered, AddressOf textBlock1_PointerEntered

Vous pouvez également supprimer des gestionnaires pour les cas où l’événement a été ajouté via un attribut XAML, ce qui signifie que le gestionnaire a été ajouté dans le code généré. Cela est plus facile à faire si vous avez fourni une valeur Nom pour l’élément où le gestionnaire a été attaché, car cela fournit une référence d’objet pour le code ultérieurement. Toutefois, vous pouvez également parcourir l’arborescence d’objets afin de trouver la référence d’objet nécessaire dans les cas où l’objet n’a pas de nom.

Si vous devez supprimer un gestionnaire d’événements en C++/CX, vous aurez besoin d’un jeton d’inscription, que vous devez recevoir de la valeur de retour de l’inscription du gestionnaire d’événements +=. Cela est dû au fait que la valeur que vous utilisez pour le côté droit de l’inscription -= dans la syntaxe C++/CX est le jeton, et non le nom de la méthode. Pour C++/CX, vous ne pouvez pas supprimer les gestionnaires qui ont été ajoutés en tant qu’attribut XAML, car le code généré par C++/CX n’enregistre pas de jeton.

Événements routés

Windows Runtime avec C#, Microsoft Visual Basic ou C++/CX prend en charge le concept d’événement routé pour un ensemble d’événements présents sur la plupart des éléments d’IU. Ces événements sont destinés aux scénarios d’entrée et d’interaction utilisateur, et ils sont implémentés sur la classe de base UIElement. Voici une liste d’événements d’entrée qui sont des événements routés :

Un événement routé est un événement potentiellement transmis (routé) d’un objet enfant à chacun de ses objets parents successifs dans une arborescence d’objets. La structure XAML de votre IU se rapproche de cette arborescence, avec la racine de cette arborescence étant l’élément racine en XAML. La véritable arborescence d’objets peut légèrement varier à partir de l’imbrication d’éléments XAML, car l’arborescence d’objets n’inclut pas de fonctionnalités de langage XAML telles que les balises d’élément de propriété. Vous pouvez concevoir l’événement routé comme une propagation à partir de n’importe quel élément enfant d’élément d’objet XAML qui déclenche l’événement, vers l’élément d’objet parent qui le contient. L’événement et ses données d’événement peuvent être gérés sur plusieurs objets le long de la route d’événement. Si aucun élément n’a de gestionnaires, la route continue d’avancer jusqu’à ce que l’élément racine soit atteint.

Si vous connaissez des technologies Web telles que Dynamic HTML (DHTML) ou HTML5, vous connaissez peut-être déjà le concept d’événement de propagation.

Lorsqu’un événement routé se propage par le biais de sa route d’événements, tous les gestionnaires d’événements attachés accèdent à une instance partagée de données d’événement. Par conséquent, si l’une des données d’événement est accessible en écriture par un gestionnaire, toutes les modifications apportées aux données d’événement sont transmises au gestionnaire suivant et peuvent ne plus représenter les données d’événement d’origine de l’événement. Lorsqu’un événement a un comportement d’événement routé, la documentation de référence inclut des remarques ou d’autres notations sur le comportement routé.

Propriété OriginalSource de RoutedEventArgs

Lorsqu’un événement se propage le long d’une route d’événement, l’expéditeur n’est plus le même objet que celui qui a déclenché l’événement. Au lieu de cela, l’expéditeur est l’objet dans lequel le gestionnaire appelé est attaché.

Dans certains cas, l’expéditeur n’est pas intéressant et vous êtes plutôt intéressé par des informations telles que les objets enfants possibles sur lesquels le pointeur est déclenché lorsqu’un événement de pointeur a été déclenché, ou quel objet dans une IU plus grande a maintenu le focus lorsqu’un utilisateur a appuyé sur une touche du clavier. Dans ce cas, vous pouvez utiliser la valeur de la propriété OriginalSource. À tous les points de l’itinéraire, OriginalSource signale l’objet d’origine qui a déclenché l’événement, au lieu de l’objet où le gestionnaire est attaché. Toutefois, pour les événements d’entrée UIElement, cet objet d’origine est souvent un objet qui n’est pas immédiatement visible dans le XAML de définition d’IU au niveau de la page. Au lieu de cela, cet objet source d’origine peut être une partie modèle d’un contrôle. Par exemple, si l’utilisateur passe sur le bord même d’un bouton, pour la plupart des événements de pointeur, l’élément OriginalSource est un composant modèle bordure dans le modèle, et non le bouton lui-même.

Conseil La propagation d’événements d’entrée est particulièrement utile si vous créez un contrôle basé sur un modèle. Tout contrôle doté d’un modèle peut avoir un nouveau modèle appliqué par son consommateur. Le consommateur qui tente de recréer un modèle de travail risque d’éliminer involontairement la gestion des événements déclarée dans le modèle par défaut. Vous pouvez toujours fournir la gestion des événements au niveau du contrôle en attachant des gestionnaires dans le cadre du remplacement OnApplyTemplate dans la définition de classe. Vous pouvez ensuite intercepter les événements d’entrée qui se déclenchent à la racine du contrôle lors de l’instanciation.

Propriété Handled

Plusieurs classes de données d’événements pour des événements routés spécifiques contiennent une propriété nommée Handled. Pour obtenir des exemples, consultez PointerRoutedEventArgs.Handled, KeyRoutedEventArgs.Handled, DragEventArgs.Handled. Dans tous les cas, Géré est une propriété booléenne settable.

La définition de la propriété Géré sur true influence le comportement du système d’événements. Lorsque Handled a la valeur true, le routage s’arrête pour la plupart des gestionnaires d’événements ; l’événement ne continue pas le long de l’itinéraire pour notifier d’autres gestionnaires attachés de ce cas d’événement particulier. Ce que signifie « géré » dans le contexte de l’événement et comment votre application répond à celle-ci. En fait, Géré est un protocole simple qui permet au code de l’application d’indiquer qu’une occurrence d’un événement n’a pas besoin de buller vers des conteneurs, votre logique d’application s’occupe des besoins faits. À l’inverse, vous devez être prudent que vous ne gérez pas les événements qui doivent probablement être propagés afin que le système intégré ou les comportements de contrôle puissent agir. Par exemple, la gestion des événements de bas niveau dans les parties ou les éléments d’un contrôle de sélection peut nuire. Le contrôle de sélection peut rechercher des événements d’entrée pour savoir que la sélection doit changer.

Tous les événements routés ne peuvent pas annuler un itinéraire de cette façon, et vous pouvez le dire, car ils n’auront pas de propriété handled. Par exemple, GotFocus et LostFocus sont propagés, mais ils sont toujours propagés jusqu’à la racine, et leurs classes de données d’événement n’ont pas de propriété gérée qui peut influencer ce comportement.

Gestionnaires d’événements d’entrée dans les contrôles

Des contrôles Windows Runtime spécifiques utilisent parfois le concept handled pour les événements d’entrée en interne. Cela peut donner l’impression qu’un événement d’entrée ne se produit jamais, car votre code utilisateur ne peut pas le gérer. Par exemple, la classe Button inclut une logique qui gère délibérément l’événement d’entrée général PointerPressed. Cela est dû au fait que les boutons déclenchent un événement Click lancé par une entrée par actionnement de pointeur, ainsi que par d’autres modes d’entrée tels que la gestion des touches comme la touche Entrée qui peut appeler le bouton lorsqu’il est mis en avant. À des fins de conception de classe de Button, l’événement d’entrée brute est géré conceptuellement, et les consommateurs de classes tels que votre code utilisateur peuvent interagir avec l’événement Click en rapport avec le contrôle. Les rubriques relatives aux classes de contrôle spécifiques dans la référence de l’API Windows Runtime notent souvent le comportement de gestion des événements que la classe implémente. Dans certains cas, vous pouvez modifier le comportement en remplaçant les méthodes OnEvent. Par exemple, vous pouvez modifier la façon dont votre classe dérivée TextBox réagit à l’entrée de clé en remplaçant Control.OnKeyDown.

Inscription de gestionnaires pour les événements routés déjà gérés

Nous avons dit précédemment que le paramètre Géré sur true empêche l’appel de la plupart des gestionnaires. Toutefois, la méthode AddHandler fournit une technique dans laquelle vous pouvez attacher un gestionnaire qui est toujours appelé pour la route, même si un autre gestionnaire antérieur dans la route a défini Handled sur true dans les données d’événement partagées. Cette technique est utile si un contrôle que vous utilisez a géré l’événement dans sa composition interne ou pour une logique spécifique au contrôle. mais vous souhaitez toujours y répondre à partir d’une instance de contrôle ou de l’interface utilisateur de votre application. Utilisez toutefois cette technique avec précaution, car elle peut contredire l’objectif de Handled et éventuellement briser les interactions prévues d’un contrôle.

Seuls les événements routés qui ont un identificateur d’événement routé correspondant peuvent utiliser la technique de gestion des événements AddHandler, car l’identificateur est une entrée requise de la méthode AddHandler. Consultez la documentation de référence pour AddHandler pour obtenir la liste des événements qui ont des identificateurs d’événement routés disponibles. Pour la plupart des cas, il s’agit de la même liste d’événements routés que celle que nous vous avons montré précédemment. L’exception est que les deux derniers de la liste : GotFocus et LostFocus n’ont pas d’identificateur d’événement routé. Vous ne pouvez donc pas utiliser AddHandler pour ceux-ci.

Événements routés en dehors de l’arborescence d'éléments visuels

Certains objets participent à une relation avec l’arborescence d’éléments visuels principale qui est conceptuellement semblable à avoir une superposition sur les visuels principaux. Ces objets ne font pas partie des relations parent-enfant habituelles qui connectent tous les éléments d’arborescence à la racine visuelle. Il s’agit du cas d’affichage d’une fenêtre contextuelle ou d’une info-bulle. Si vous souhaitez gérer les événements routés à partir d’une Fenêtre contextuelle ou d’une Info-bulle, placez les gestionnaires sur des éléments d’interface utilisateur spécifiques qui se trouvent dans la Fenêtre contextuelle ou l’Info-bulle et non les éléments Fenêtre contextuelle ou Info-bulle eux-mêmes. Ne vous fiez pas au routage à l’intérieur d’une composition effectuée pour le contenu Fenêtre contextuelle ou Info-bulle. Cela est dû au fait que le routage d'événement des événements routés fonctionne uniquement le long de l’arborescence visuelle principale. Une fenêtre contextuelle ou info-bulle n’est pas considérée comme un parent d’éléments d’IU filiale et ne reçoit jamais l’événement routé, même s’il tente d’utiliser quelque chose comme l’arrière-plan par défaut de la fenêtre contextuelle comme zone de capture pour les événements d’entrée.

Tests de positionnement et événements d’entrée

Déterminer si, dans l’IU, un élément est visible par la souris, la touche tactile et l’entrée de stylet est appelé test de positionnement. Pour les actions tactiles et pour les événements spécifiques à l’interaction ou de manipulation qui sont des conséquences d’une action tactile, un élément doit être visible par un test de positionnement pour être la source de l'événement et déclencher l’événement associé à l’action. Sinon, l’action passe par l’élément vers tous les éléments sous-jacents ou les éléments parents de l’arborescence visuelle qui peuvent interagir avec cette entrée. Il existe plusieurs facteurs qui affectent les tests de positionnement, mais vous pouvez déterminer si un élément donné peut déclencher des événements d’entrée en vérifiant sa propriété IsHitTestVisible. Cette propriété retourne true uniquement si l’élément répond à ces critères :

  • La valeur de la propriété Visibility de l’élément est Visible.
  • La valeur de la propriété Arrière-plan ou Fill de l’élément n’est pas null. Une valeur de pinceauNull entraîne la transparence et l’invisibilité du test de positionnement. (Pour rendre un élément transparent mais également testable, utilisez un Pinceau transparent au lieu de null.)

Notez quel’arrière-plan et le remplissage ne sont pas définis par UIElement et sont plutôt définis par différentes classes dérivées telles que Control et Shape. Toutefois, les implications des pinceaux que vous utilisez pour les propriétés de premier plan et d’arrière-plan sont les mêmes pour les tests de positionnement et les événements d’entrée, quelle que soit la sous-classe qui implémente les propriétés.

  • Si l’élément est un contrôle, sa valeur de propriété IsEnabled doit être true.
  • L’élément doit avoir des dimensions réelles dans la disposition. Un élément où ActualHeight et ActualWidth sont 0 ne déclenche pas d’événements d’entrée.

Certains contrôles ont des règles spéciales pour le test de positionnement. Par exemple, TextBlock n’a pas de propriété d’arrière-plan, mais est toujours testable dans la région entière de ses dimensions. Les contrôles Image et MediaElement sont testables sur leurs dimensions de rectangle définies, quel que soit le contenu transparent tel que le canal alpha dans le fichier source multimédia affiché. Les contrôles WebView ont un comportement de test de positionnement spécial, car l’entrée peut être gérée par le code HTML hébergé et déclencher des événements de script.

La plupart des classes Panel et Border ne peuvent pas faire l’objet d’un test de positionnement en arrière-plan, mais peuvent toujours gérer les événements d’entrée utilisateur routés à partir des éléments qu’ils contiennent.

Vous pouvez déterminer quels éléments se trouvent à la même position qu’un événement d’entrée utilisateur, que les éléments puissent faire l’objet d’un test de positionnement ou non. Pour ce faire, appelez la méthode FindElementsInHostCoordinates. Comme le nom l’indique, cette méthode recherche les éléments à un emplacement par rapport à un élément hôte spécifié. Toutefois, les transformations appliquées et les modifications de layout peuvent ajuster le système de coordonnées relatif d’un élément, et donc affecter les éléments trouvés à un emplacement donné.

Commandes

Un petit nombre d’éléments d’IU prennent en charge les commandes. La commande utilise des événements routés liés aux entrées dans son implémentation sous-jacente et permet le traitement de l’entrée d’IU associée (une action de pointeur spécifique, une touche d’accélérateur spécifique) en appelant un seul gestionnaire de commandes. Si la commande est disponible pour un élément d’IU, envisagez d’utiliser ses API de commande au lieu d’événements d’entrée discrets. Vous utilisez généralement une référence Binding dans les propriétés d’une classe qui définit le modèle de vue pour les données. Les propriétés contiennent des commandes nommées qui implémentent le modèle de commande ICommand spécifique à une langue. Pour plus d’informations, consultez ButtonBase.Command.

Événements personnalisés dans Windows Runtime

Pour définir des événements personnalisés, la façon dont vous ajoutez l’événement et ce que cela signifie pour votre conception de classe dépend fortement du langage de programmation que vous utilisez.

  • Pour C# et Visual Basic, vous définissez un événement CLR. Vous pouvez utiliser le modèle d’événement .NET standard, tant que vous n’utilisez pas d’accesseurs personnalisés (ajouter/supprimer). Astuces supplémentaires :
  • Pour C++/CX, consultez Événements (C++/CX).
    • Utilisez des références nommées même pour vos propres utilisations d’événements personnalisés. N’utilisez pas lambda pour les événements personnalisés , une référence circulaire pourrait être créée.

Vous ne pouvez pas déclarer d’événement routé personnalisé pour Windows Runtime ; les événements routés sont limités à l’ensemble qui provient de Windows Runtime.

La définition d’un événement personnalisé est généralement effectuée dans le cadre de l’exercice de définition d’un contrôle personnalisé. Il s’agit d’un modèle courant pour avoir une propriété de dépendance qui a un rappel modifié par une propriété et pour définir également un événement personnalisé déclenché par le rappel de propriété de dépendance dans certains cas ou tous les cas. Les consommateurs de votre contrôle n’ont pas accès au rappel modifié par la propriété que vous avez défini, mais le fait d’avoir un événement de notification disponible est la meilleure chose à suivre. Pour plus d’informations, consultez Propriétés de dépendance personnalisées.