2010-08-05 35 views
4

J'essaie de tester un tas de UserControls sur un canevas. Je ne veux pas que HitTest() marche tout au long de l'arborescence visuelle, donc j'utilise le FilterCallback pour m'assurer que je ne fais que tester le UserControl.Problème avec VisualTreeHelper.HitTest dans WPF

Mon problème est que le UserControl ne frappe jamais, il devrait, mais ce n'est pas le cas. Si j'utilise le FilterCallback, je reviens qu'il n'a rien touché. Si je laisse le HitTest parcourir l'arborescence visuelle, il ignore le UserControl.

Voici un code:

<Canvas x:Name="Container"> 
<UserControl> 
    <Grid> 
     <Rectangle /> 
    </Grid> 
</UserControl> 
<UserControl> 
    <Grid> 
     <Rectangle /> 
    </Grid> 
</UserControl> 
</Canvas> 

... 
VisualTreeHelper.HitTest(Container, OnFilter, OnResult, myPoint); 
... 

private void OnResult(DependencyObject o) 
{ 
    //I'll get the Rectangle here, but never the userControl 
} 

private void OnFilter(DependencyObject o) 
{ 
    //I will get the UserControl here, but even when I do nothing more than continue, it will not trigger a visualHit. But the child rectangle will. 
} 

Répondre

2

J'ai eu ce même problème de ne pas trouver HitTest un contrôle utilisateur. Apparemment, c'est par conception (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/005dad03-c8eb-405f-9567-50653a0e612c).

J'ai travaillé autour de cela en gérant le hit de certains éléments dans le contrôle utilisateur, puis en trouvant le contrôle utilisateur parent en utilisant la méthode VisualTreeHelper.GetParent. Je ne suis pas encore très familier avec WPF, donc je ne suis pas sûr qu'il serait préférable d'utiliser la propriété FrameworkElement.Parent.

Cependant, voici ma méthode pour trouver le contrôle de l'utilisateur (ou tout autre parent visuel d'un certain type requis) après la première recherche de certains de ses éléments de contenu par test de recherche:

public static T GetVisualParent<T>(this DependencyObject element) where T : DependencyObject 
{ 
    while (element != null && !(element is T)) 
     element = VisualTreeHelper.GetParent(element); 

    return (T)element; 
} 
11

Je sais qu'il est sacrément en retard pour répondre à cela, mais ici va: une approche différente est de passer outre HitTestCore sur le UserControl et lui fournir le comportement par défaut qui en attendre:

protected override System.Windows.Media.HitTestResult HitTestCore(System.Windows.Media.PointHitTestParameters hitTestParameters) 
{ 
    return new PointHitTestResult(this, hitTestParameters.HitPoint); 
} 

(bien sûr, vous pouvez compliquer les choses et a frappé test la enfants réels ou th La combinaison de leurs boîtes de délimitation, mais pour moi la boîte de contrôle de l'utilisateur était assez bon; De plus, si vous voulez tester la géométrie, vous devez aussi surcharger cette seconde surcharge.)

Ceci le fait fonctionner comme prévu, filtrant les enfants lors de l'utilisation de HitTestFilterBehavior.ContinueSkipChildren dans le filtre.

+0

Peut confirmer que cela fonctionne. Devrait être la réponse acceptée car c'est mieux que de chercher dans l'arbre visuel manuellement. – Lennart