Home > Back-end >  Why is my hit test bringing back way too many items?
Why is my hit test bringing back way too many items?

Time:01-28

I've got a hit test I'm using on a canvas with a bunch of lines loaded from a dxf file and it's returning an unexpectedly large amount of line objects each time even though my ellipse geometry is quite small. See below:

 private void map_page_canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var selectedElements = new List<DependencyObject>();
            Point pt = e.GetPosition((UIElement)sender);
            var rect = new EllipseGeometry(pt, 0.5, 0.5);

            var hitTestParams = new GeometryHitTestParameters(rect);

            var resultCallback = new HitTestResultCallback(
                result => HitTestResultBehavior.Continue);

            var filterCallback = new HitTestFilterCallback(
                element =>
                {
                    if (VisualTreeHelper.GetParent(element) == map_page_canvas)
                    {
                        selectedElements.Add(element);
                    }
                    return HitTestFilterBehavior.Continue;
                });

            VisualTreeHelper.HitTest(
                map_page_canvas, filterCallback, resultCallback, hitTestParams);

            foreach (var element in selectedElements)
            {
                Console.WriteLine(element.GetType());
            }
        }

Here's the canvas setup:

  <Canvas Background="Transparent"
        Grid.Column="1" Grid.Row="1"
        ClipToBounds="True"
        SizeChanged="ViewportSizeChanged"
        MouseLeftButtonDown="ViewportMouseLeftButtonDown"
        MouseLeftButtonUp="ViewportMouseLeftButtonUp"
        MouseMove="ViewportMouseMove"
        MouseWheel="ViewportMouseWheel">
            <Canvas x:Name="map_page_canvas" Width="800" Height="500" ClipToBounds="False"
                        Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center"
                        VerticalAlignment="Center" Background="White" MouseWheel="ViewportMouseWheel" MouseLeftButtonDown="map_page_canvas_MouseLeftButtonDown"
                        >
                <Canvas.LayoutTransform>
                    <ScaleTransform ScaleX="1" ScaleY="-1" CenterX="1" CenterY="1" />
                </Canvas.LayoutTransform>
                <Canvas.RenderTransform>
                    <MatrixTransform x:Name="transform"/>
                </Canvas.RenderTransform>
            </Canvas>
        </Canvas>
        <Border BorderThickness="0.5 0.5 0 0.5" BorderBrush="Black" 
            Grid.Column="1" Grid.Row="1"/>

CodePudding user response:

Adding elements should be done in the HitTestResultCallback, not in the HitTestFilterCallback. In fact, you should not use a HitTestFilterCallback at all.

var resultCallback = new HitTestResultCallback(
    result =>
    {
        if (VisualTreeHelper.GetParent(result.VisualHit) == map_page_canvas)
        {
            hitList.Add(result.VisualHit);
        }
                
        return HitTestResultBehavior.Continue;
    });

...

VisualTreeHelper.HitTest(map_page_canvas, null, resultCallback, hitTestParams);

CodePudding user response:

For whatever reason, replacing my filterCallback variable with a method fixed my issue. See below method:

 private HitTestResultBehavior MyHitTestResult(HitTestResult result)
        {
            if (VisualTreeHelper.GetParent(result.VisualHit) == map_page_canvas)
            {
                hitList.Add(result.VisualHit);
            }  

            return HitTestResultBehavior.Continue; 
        }
  • Related