Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cette rubrique fournit une vue d’ensemble de la fonctionnalité de test de positionnement fournie par la couche visuelle. La prise en charge du test de positionnement vous permet de déterminer si la valeur d’une géométrie ou d’un point se situe dans le contenu rendu d’un Visual, ce qui vous permet d’implémenter un comportement de type interface utilisateur comme un rectangle de sélection pour sélectionner plusieurs objets.
Scénarios de test de positionnement
La classe UIElement fournit la méthode InputHitTest, qui vous permet d’effectuer un test sur un élément à l’aide d’une valeur de coordonnée donnée. Dans de nombreux cas, la méthode InputHitTest fournit les fonctionnalités souhaitées pour implémenter le test de collision des éléments. Toutefois, il existe plusieurs scénarios dans lesquels il pourrait être nécessaire d'implémenter des tests de détection de clic dans la couche visuelle.
Tests de positionnement sur des objets nonUIElement : cela s'applique si vous testez des objets nonUIElement, tels que des objets DrawingVisual ou des objets graphiques.
Test de positionnement à l’aide d’une géométrie : cela s’applique si vous avez besoin d’effectuer un test de positionnement à l’aide d’un objet géométrique plutôt que la valeur des coordonnées d’un point.
Test de collision sur plusieurs objets : ceci s'applique lorsque vous devez réaliser un test de collision sur plusieurs objets, tels que des objets qui se chevauchent. Vous pouvez obtenir des résultats pour tous les visuels qui croisent une géométrie ou un point, pas seulement le premier.
Ignorer la stratégie de test de positionnement UIElement : cela s'applique lorsque vous devez ignorer la stratégie de test de positionnement UIElement, qui prend en compte des facteurs tels que le fait qu'un élément soit désactivé ou invisible.
Remarque
Pour obtenir un exemple de code complet illustrant les tests d’accès au niveau de la couche visuelle, consultez Test d’accès à l’aide de l’exemple dessinVisuals et Test d’accès avec l’exemple d’interopérabilité Win32.
Prise en charge du test de positionnement
L'objectif des méthodes HitTest dans la classe VisualTreeHelper est de déterminer si une valeur de géométrie ou de coordonnée de point se trouve dans le contenu rendu d'un objet donné, tel qu'un composant ou un élément graphique. Par exemple, vous pouvez utiliser le test de positionnement pour déterminer si un clic de souris dans le rectangle englobant d’un objet se trouve dans la géométrie d’un cercle. Vous pouvez également choisir de remplacer l’implémentation par défaut des tests de collision pour effectuer vos propres calculs de test d'impact personnalisés.
L’illustration suivante montre la relation entre la région d’un objet non rectangulaire et son rectangle englobant.
Diagramme 
Diagramme de la zone de test de contact valide
Hit Testing et Z-Order
La couche visuelle Windows Presentation Foundation (WPF) prend en charge le test de positionnement sur tous les objets sous un point ou une géométrie, pas seulement l’objet de niveau supérieur. Les résultats sont renvoyés dans l'ordre Z. Toutefois, l’objet visuel que vous passez en tant que paramètre à la méthode HitTest détermine la partie de l’arborescence visuelle qui sera testée. Vous pouvez effectuer un test de positionnement sur l’arborescence visuelle entière ou une portion de celle-ci.
Dans l’illustration suivante, l’objet cercle se trouve au-dessus des objets carrés et triangles. Si vous voulez uniquement effectuer un test de positionnement sur l’objet visuel dont la valeur d’ordre de plan est la plus élevée, vous pouvez définir l’énumération de test de positionnement visuelle pour qu’elle renvoie Stop à partir de HitTestResultCallback afin d’interrompre le parcours du test de positionnement après le premier élément.
diagramme 
Diagramme de l’ordre z d’une arborescence visuelle
Si vous souhaitez énumérer tous les objets visuels sous un point ou une géométrie spécifique, retournez Continue à partir du HitTestResultCallback. Cela signifie que vous pouvez tester les objets visuels qui se trouvent sous d’autres objets, même s’ils sont entièrement masqués. Pour plus d’informations, consultez l’exemple de code dans la section « Utilisation du rappel des résultats d’un test de positionnement ».
Remarque
Un objet visuel transparent peut également être soumis à un test de collision.
Utilisation du test de collision par défaut
Vous pouvez identifier si un point se trouve dans la géométrie d’un objet visuel, à l’aide de la méthode HitTest pour spécifier un objet visuel et une valeur de coordonnée de point à tester. Le paramètre de l’objet visuel identifie le point de départ dans l’arborescence visuelle pour la recherche du test de positionnement. Si un objet visuel se trouve dans l’arborescence visuelle dont la géométrie contient la coordonnée, elle est définie sur la propriété VisualHit d’un objet HitTestResult. La valeur HitTestResult est ensuite renvoyée par la méthode HitTest. Si le point n’est pas contenu dans la sous-arborescence visuelle que vous évaluez, HitTest retourne null.
Remarque
Le test de positionnement par défaut retourne toujours l’objet de plus haut niveau dans l’ordre de plan. Pour identifier tous les objets visuels, même ceux qui peuvent être partiellement ou entièrement masqués, utilisez un rappel de résultat de test d'impact.
La valeur de coordonnée que vous passez en tant que paramètre de point pour la méthode HitTest doit être relative à l’espace de coordonnées de l’objet visuel sur lequel vous effectuez des tests. Par exemple, si vous avez imbriqué des objets visuels définis sur (100, 100) dans l’espace des coordonnées du parent, alors le test de positionnement sur un objet visuel enfant à (0, 0) est équivalent au test de positionnement sur (100, 100) dans l’espace des coordonnées du parent.
Le code suivant montre comment configurer des gestionnaires d’événements de souris pour un objet UIElement utilisé pour capturer des événements utilisés pour les tests de collision.
// Respond to the left mouse button down event by initiating the hit test.
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Retrieve the coordinate of the mouse position.
Point pt = e.GetPosition((UIElement)sender);
// Perform the hit test against a given portion of the visual object tree.
HitTestResult result = VisualTreeHelper.HitTest(myCanvas, pt);
if (result != null)
{
// Perform action on hit visual object.
}
}
' Respond to the left mouse button down event by initiating the hit test.
Private Overloads Sub OnMouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
' Retrieve the coordinate of the mouse position.
Dim pt As Point = e.GetPosition(CType(sender, UIElement))
' Perform the hit test against a given portion of the visual object tree.
Dim result As HitTestResult = VisualTreeHelper.HitTest(myCanvas, pt)
If result IsNot Nothing Then
' Perform action on hit visual object.
End If
End Sub
Impact de l’arborescence visuelle sur le test de positionnement
Le point de départ dans l’arborescence visuelle détermine quels objets sont retournés lors de l’énumération du test de positionnement des objets. Si vous avez plusieurs objets que vous souhaitez tester, l’objet visuel utilisé comme point de départ dans l’arborescence visuelle doit être l’ancêtre commun de tous les objets intéressants. Par exemple, si vous voulez effectuer un test de positionnement sur l’élément bouton et l’objet visuel de dessin dans le diagramme suivant, vous devez définir le point de départ dans l’arborescence visuelle sur l’ancêtre commun des deux. Dans ce cas, l’élément canevas est l’ancêtre commun de l’élément bouton et de l’objet visuel de dessin.
Diagramme 
Diagramme d’une hiérarchie d’arborescences visuelles
Remarque
La propriété IsHitTestVisible obtient ou définit une valeur qui indique si un objet dérivé de UIElementpeut être renvoyé en tant que résultat d'un test de collision à partir d'une partie de son contenu rendu. Cela vous permet de modifier de manière sélective l’arborescence visuelle afin de déterminer les objets visuels impliqués dans un test de positionnement.
Utilisation d'une fonction de rappel de résultat de Hit Test
Vous pouvez énumérer tous les objets visuels dans une arborescence visuelle dont la géométrie contient une valeur de coordonnée spécifiée. Cela vous permet d’identifier tous les objets visuels, même ceux qui peuvent être partiellement ou entièrement masqués par d’autres objets visuels. Pour énumérer les objets visuels dans une arborescence visuelle, utilisez la méthode HitTest avec une fonction de rappel du test de positionnement. La fonction de rappel de test de collision est appelée par le système lorsque la valeur de coordonnée que vous spécifiez est contenue dans un objet visuel.
Lors de l’énumération des résultats du test de positionnement, vous ne devez effectuer aucune opération susceptible de modifier l’arborescence visuelle. L’ajout ou la suppression d’un objet de l’arborescence visuelle pendant qu’il est parcouru peut entraîner un comportement imprévisible. Vous pouvez modifier en toute sécurité l’arborescence d’éléments visuels une fois la méthode HitTest retournée. Vous pouvez fournir une structure de données, comme ArrayList, pour stocker des valeurs lors de l’énumération des résultats du test de positionnement.
// Respond to the right mouse button down event by setting up a hit test results callback.
private void OnMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
// Retrieve the coordinate of the mouse position.
Point pt = e.GetPosition((UIElement)sender);
// Clear the contents of the list used for hit test results.
hitResultsList.Clear();
// Set up a callback to receive the hit test result enumeration.
VisualTreeHelper.HitTest(myCanvas, null,
new HitTestResultCallback(MyHitTestResult),
new PointHitTestParameters(pt));
// Perform actions on the hit test results list.
if (hitResultsList.Count > 0)
{
Console.WriteLine("Number of Visuals Hit: " + hitResultsList.Count);
}
}
' Respond to the right mouse button down event by setting up a hit test results callback.
Private Overloads Sub OnMouseRightButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
' Retrieve the coordinate of the mouse position.
Dim pt As Point = e.GetPosition(CType(sender, UIElement))
' Clear the contents of the list used for hit test results.
hitResultsList.Clear()
' Set up a callback to receive the hit test result enumeration.
VisualTreeHelper.HitTest(myCanvas, Nothing, New HitTestResultCallback(AddressOf MyHitTestResult), New PointHitTestParameters(pt))
' Perform actions on the hit test results list.
If hitResultsList.Count > 0 Then
Console.WriteLine("Number of Visuals Hit: " & hitResultsList.Count)
End If
End Sub
La méthode de rappel de test de collision définit les actions que vous effectuez lorsqu’un test de collision est détecté sur un objet graphique particulier dans l’arborescence visuelle. Après avoir effectué les actions, vous retournez une valeur HitTestResultBehavior qui détermine s’il faut continuer l’énumération d’autres objets visuels ou non.
// Return the result of the hit test to the callback.
public HitTestResultBehavior MyHitTestResult(HitTestResult result)
{
// Add the hit test result to the list that will be processed after the enumeration.
hitResultsList.Add(result.VisualHit);
// Set the behavior to return visuals at all z-order levels.
return HitTestResultBehavior.Continue;
}
' Return the result of the hit test to the callback.
Public Function MyHitTestResult(ByVal result As HitTestResult) As HitTestResultBehavior
' Add the hit test result to the list that will be processed after the enumeration.
hitResultsList.Add(result.VisualHit)
' Set the behavior to return visuals at all z-order levels.
Return HitTestResultBehavior.Continue
End Function
Remarque
L'ordre d'énumération des objets visuels touchés est par ordre Z. L’objet visuel au niveau de l’ordre z le plus élevé est le premier objet énuméré. Tous les autres objets visuels énumérés sont à un niveau de classement z décroissant. Cet ordre d’énumération correspond à l’ordre de rendu des visuels.
Vous pouvez arrêter l’énumération des objets visuels à tout moment dans la fonction de rappel du test de positionnement en retournant Stop.
// Set the behavior to stop enumerating visuals.
return HitTestResultBehavior.Stop;
' Set the behavior to stop enumerating visuals.
Return HitTestResultBehavior.Stop
Utilisation d’un rappel de filtre du test de positionnement
Vous pouvez utiliser un filtre de test de collision facultatif pour restreindre les objets transmis aux résultats des tests de collision. Ceci vous permet d’ignorer les parties de l’arborescence d’éléments visuels que vous ne souhaitez pas traiter dans vos résultats de test de positionnement. Pour implémenter un filtre de test de positionnement, vous définissez une fonction de rappel de filtre de test de positionnement et transmettez-la en tant que valeur de paramètre lorsque vous appelez la méthode HitTest.
// Respond to the mouse wheel event by setting up a hit test filter and results enumeration.
private void OnMouseWheel(object sender, MouseWheelEventArgs e)
{
// Retrieve the coordinate of the mouse position.
Point pt = e.GetPosition((UIElement)sender);
// Clear the contents of the list used for hit test results.
hitResultsList.Clear();
// Set up a callback to receive the hit test result enumeration.
VisualTreeHelper.HitTest(myCanvas,
new HitTestFilterCallback(MyHitTestFilter),
new HitTestResultCallback(MyHitTestResult),
new PointHitTestParameters(pt));
// Perform actions on the hit test results list.
if (hitResultsList.Count > 0)
{
ProcessHitTestResultsList();
}
}
' Respond to the mouse wheel event by setting up a hit test filter and results enumeration.
Private Overloads Sub OnMouseWheel(ByVal sender As Object, ByVal e As MouseWheelEventArgs)
' Retrieve the coordinate of the mouse position.
Dim pt As Point = e.GetPosition(CType(sender, UIElement))
' Clear the contents of the list used for hit test results.
hitResultsList.Clear()
' Set up a callback to receive the hit test result enumeration.
VisualTreeHelper.HitTest(myCanvas, New HitTestFilterCallback(AddressOf MyHitTestFilter), New HitTestResultCallback(AddressOf MyHitTestResult), New PointHitTestParameters(pt))
' Perform actions on the hit test results list.
If hitResultsList.Count > 0 Then
ProcessHitTestResultsList()
End If
End Sub
Si vous ne souhaitez pas fournir la fonction de rappel de filtre de test de positionnement facultatif, transmettez une valeur null comme paramètre de celle-ci pour la méthode HitTest.
// Set up a callback to receive the hit test result enumeration,
// but no hit test filter enumeration.
VisualTreeHelper.HitTest(myCanvas,
null, // No hit test filtering.
new HitTestResultCallback(MyHitTestResult),
new PointHitTestParameters(pt));
' Set up a callback to receive the hit test result enumeration,
' but no hit test filter enumeration.
VisualTreeHelper.HitTest(myCanvas, Nothing, New HitTestResultCallback(AddressOf MyHitTestResult), New PointHitTestParameters(pt)) ' No hit test filtering.
Élagage d’une arborescence visuelle
La fonction de rappel de filtre de test de positionnement permet d’énumérer tous les objets visuels dont le contenu rendu contient les coordonnées que vous spécifiez. Toutefois, vous pouvez ignorer certaines branches de l’arborescence d’éléments visuels que vous ne souhaitez pas traiter dans votre fonction de rappel des résultats de test de positionnement. La valeur de retour de la fonction de rappel de filtre de test de positionnement détermine le type d’action que l’énumération des objets visuels doit prendre. Par exemple, si vous retournez la valeur, ContinueSkipSelfAndChildren, vous pouvez supprimer l’objet visuel actuel et ses enfants de l’énumération des résultats du test de positionnement. Cela signifie que la fonction de rappel des résultats des tests de collision ne verra pas ces objets dans son énumération. L’élagage des objets dans l’arborescence visuelle diminue la quantité de traitement au cours de la passe de l’énumération des résultats de test de positionnement. Dans l’exemple de code suivant, le filtre ignore les étiquettes et leurs descendants et effectue un test de positionnement sur tout le reste.
// Filter the hit test values for each object in the enumeration.
public HitTestFilterBehavior MyHitTestFilter(DependencyObject o)
{
// Test for the object value you want to filter.
if (o.GetType() == typeof(Label))
{
// Visual object and descendants are NOT part of hit test results enumeration.
return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
}
else
{
// Visual object is part of hit test results enumeration.
return HitTestFilterBehavior.Continue;
}
}
' Filter the hit test values for each object in the enumeration.
Public Function MyHitTestFilter(ByVal o As DependencyObject) As HitTestFilterBehavior
' Test for the object value you want to filter.
If o.GetType() Is GetType(Label) Then
' Visual object and descendants are NOT part of hit test results enumeration.
Return HitTestFilterBehavior.ContinueSkipSelfAndChildren
Else
' Visual object is part of hit test results enumeration.
Return HitTestFilterBehavior.Continue
End If
End Function
Remarque
Le rappel de filtre du test de positionnement est parfois appelé dans les cas où le rappel des résultats du test d’atteinte n’est pas appelé.
Remplacement du test de collision par défaut
Vous pouvez substituer la prise en charge par défaut du test de positionnement d’un objet visuel en substituant la méthode HitTestCore. Cela signifie que lorsque vous appelez la méthode HitTest, votre implémentation substituée de HitTestCore est appelée. Votre méthode substituée est appelée lorsqu’un test de positionnement se situe dans le rectangle englobant de l’objet visuel, même si les coordonnées se situent en dehors du contenu rendu de l’objet visuel.
// Override default hit test support in visual object.
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
Point pt = hitTestParameters.HitPoint;
// Perform custom actions during the hit test processing,
// which may include verifying that the point actually
// falls within the rendered content of the visual.
// Return hit on bounding rectangle of visual object.
return new PointHitTestResult(this, pt);
}
' Override default hit test support in visual object.
Protected Overrides Overloads Function HitTestCore(ByVal hitTestParameters As PointHitTestParameters) As HitTestResult
Dim pt As Point = hitTestParameters.HitPoint
' Perform custom actions during the hit test processing,
' which may include verifying that the point actually
' falls within the rendered content of the visual.
' Return hit on bounding rectangle of visual object.
Return New PointHitTestResult(Me, pt)
End Function
Vous voudrez parfois effectuer un nouveau test de positionnement sur le rectangle englobant et le contenu rendu d’un objet visuel. En utilisant la valeur de paramètre PointHitTestParameters dans votre méthode HitTestCore substituée en tant que paramètre de la méthode de base HitTestCore, vous pouvez effectuer des actions basées sur le positionnement du rectangle englobant d’un objet visuel, puis vous pouvez effectuer un deuxième test de positionnement sur le contenu rendu de l’objet visuel.
// Override default hit test support in visual object.
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
// Perform actions based on hit test of bounding rectangle.
// ...
// Return results of base class hit testing,
// which only returns hit on the geometry of visual objects.
return base.HitTestCore(hitTestParameters);
}
' Override default hit test support in visual object.
Protected Overrides Overloads Function HitTestCore(ByVal hitTestParameters As PointHitTestParameters) As HitTestResult
' Perform actions based on hit test of bounding rectangle.
' ...
' Return results of base class hit testing,
' which only returns hit on the geometry of visual objects.
Return MyBase.HitTestCore(hitTestParameters)
End Function
Voir aussi
- HitTest
- HitTestResult
- HitTestResultCallback
- HitTestFilterCallback
- IsHitTestVisible
- Exemple de test de positionnement avec DrawingVisuals
- Exemple de test de positionnement avec interopérabilité Win32
- Effectuer un test de positionnement avec Geometry dans un visuel
- Test de positionnement à l’aide d’un conteneur hôte Win32
.NET Desktop feedback