2010-12-01 24 views
0

J'ai quelques panneaux A personnalisés sur un canevas, où il y a aussi des panneaux B, comment puis-je compter A panneaux situés réellement le curseur de la souris?comptez les contrôles de type A sous la souris dans WPF

Je sais que cela pourrait être réalisé avec VisualTreeHelper.HitTest, mais n'a pas eu beaucoup de chance, il renvoie toujours les éléments sur les panneaux personnalisés ou rien du tout ...

ceci est mon code

<UserControl x:Class="WpfApplication7.UserControl1"> 
    <Grid> 
     <Label Content="Label" Height="44" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" Width="78" Background="#FF4B9FC4" BorderBrush="#FF020A0D" BorderThickness="1" /> 
    </Grid> 
</UserControl> 

<Window x:Class="WpfApplication7.MainWindow" 
PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown" xmlns:my="clr-namespace:WpfApplication7"> 
    <Grid> 
     <my:UserControl1 HorizontalAlignment="Left" Margin="82,88,0,0" x:Name="userControl11" VerticalAlignment="Top" /> 
     <my:UserControl1 HorizontalAlignment="Left" Margin="168,166,0,0" x:Name="userControl12" VerticalAlignment="Top" /> 
     <my:UserControl1 HorizontalAlignment="Left" Margin="231,130,0,0" x:Name="userControl13" VerticalAlignment="Top" /> 
    </Grid> 
</Window> 

.cs

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    List<UserControl1> ucs = new List<UserControl1>(); 

    private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     GetUcsCount(e); 
     Console.WriteLine("ucs.Count = {0}", ucs.Count); 
    } 

    private void GetUcsCount(MouseButtonEventArgs e) 
    { 
     ucs.Clear(); 

     Point p = e.GetPosition(this); 

     VisualTreeHelper.HitTest(this, null, 
      new HitTestResultCallback(MyHitTestCallback), 
      new PointHitTestParameters(p)); 
    } 

    HitTestResultBehavior MyHitTestCallback(HitTestResult result) 
    { 
     if (result.VisualHit.GetType() == typeof(UserControl1)) 
     { 
      ucs.Add(result.VisualHit as UserControl1); 
     } 

     return HitTestResultBehavior.Continue; 
    } 
} 

le result == 0 où je clique ...

alt text

Répondre

1

Pour chaque coup dans le HitTestResultCallback vous pouvez essayer de trouver le parent UserControl1 et l'ajouter à la liste si elle n'a pas encore été ajouté

HitTestResultBehavior MyHitTestCallback(HitTestResult result) 
{ 
    DependencyObject visualHit = result.VisualHit; 
    UserControl1 parentUserControl = GetVisualParent<UserControl1>(visualHit); 
    if (parentUserControl != null && ucs.IndexOf(parentUserControl) < 0) 
    { 
     ucs.Add(parentUserControl as UserControl1); 
    } 
    return HitTestResultBehavior.Continue; 
} 
public static T GetVisualParent<T>(object childObject) where T : Visual 
{ 
    DependencyObject child = childObject as DependencyObject; 
    while ((child != null) && !(child is T)) 
    { 
     child = VisualTreeHelper.GetParent(child); 
    } 
    return child as T; 
} 
+0

merci, je cela aussi respecter lors, mais maintenant il retourne trop d'éléments :(pas seulement sous la souris – serhio

+0

@serhio: Je ne trouve aucune situation où j'obtiens un élément dans le FilterCallback qui n'est pas sous la souris. Quand cela arrive-t-il? –

+0

@Meleak: J'ai compris pourquoi, en fait, myusercontrol était transparent, mais grand, et les éléments childs seulement vraiment visibles .. maintenant, je recherche une méthode qui comptera les UserControls après le hit sur l'enfant pas sur la partie transparente ... – serhio