question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

HitTest is buggy / not accurate when the UserControl's RenderTransform set to a large scale(ScaleX = ScaleY = 500)

See original GitHub issue

Description

.NET 6 or higher / WPF

I have set UserControl’s RenderTransform to a ScaleTransform(ScaleX = ScaleY = 500), and set the UserControl’s Template to be a Line shape. However, when running the application, I noticed that the mouse events of UserControl are triggered when the mouse click or move in the blank area near the line. When I set the scale to a smaller value,like ScaleX = ScaleY = 1, I don’t encounter this issue.

I find an similar problem here(https://social.msdn.microsoft.com/Forums/vstudio/en-US/8708e340-f734-4cf4-b91d-28b49fee2b72/hittest-is-buggy-not-accurate-for-transformed-scaled-etc-visuals?forum=wpf), but it seems that it has not been fixed yet.

Click in the blank area near the line: 1

Reproduction Steps

My demo code in github: https://github.com/yao-xiaofei/ShapeTest

Here is my code:

    <Grid>
        <UserControl PreviewMouseLeftButtonDown="UserControl_PreviewMouseLeftButtonDown">
            <UserControl.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="500" ScaleY="500" />
                </TransformGroup>
            </UserControl.RenderTransform>
            <UserControl.Template>
                <ControlTemplate>
                    <Line
                        Stroke="Lime"
                        StrokeThickness="0.01"
                        UseLayoutRounding="True"
                        X1="0.4"
                        X2="0.8"
                        Y1="0.3"
                        Y2="0.3" />
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Cursor" Value="Cross" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </UserControl.Template>
        </UserControl>
    </Grid>

Expected behavior

My expectation is that when I set a larger scale value(ScaleX = ScaleY = 500 or larger), the UserControl should only respond to mouse events when clicking on the area of the line, and avoid triggering mouse events in the blank area.

2

Actual behavior

The mouse events of UserControl are triggered when the mouse click or move in the blank area near the line.

Click in the blank area near the line: 1

Regression?

No response

Known Workarounds

No response

Impact

No response

Configuration

No response

Other information

No response

Issue Analytics

  • State:open
  • Created 3 months ago
  • Reactions:1
  • Comments:12 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
weltkantecommented, Jul 11, 2023

I am not sure how performance would be impacted with a double value change, you still need to do the same calculations.

This is precision for geometry and should roughly have a linear correlation with the number of subdivisions required, i.e. double the precision requires double the number of geometry segments in the calculations. Changes in this value should have a linear effect to performance and perhaps even on memory if the resulting geometry is actually stored instead of just being hit tested. (This constant is used in more methods than just hit testing methods but I didn’t research how often those are called without supplying a specific precision).

1reaction
weltkantecommented, Jul 11, 2023

Ok, was able to repro and found the cause, its the builtin default precision of the WPF geometry system, hardcoded to be 0.25 by default.

Since your lines are much finer (0.01 thickness) the default geometry precision is not sufficient. This has nothing to do with the scaling you are doing, this depends on the absolute numbers since the hit testing is done in the original scale not in the scale they are rendered at. You can construct a LineGeometry and do a hit test against it via StrokeContains and it will be very inaccurate with the thickness and coordinates you are using.

The geometry API has overloads that allow you to specify a precision, if you use that and set it appropriately then the hit test will work. Unfortunately this means you’ll have to override hit testing for everything you are zoomin in at such high scales. It seems like an oversight that WPF doesn’t derive or propagate the required precision from the LayoutTransform, but it is what it is, I don’t think this will be changed at this point.

An alternative to overriding hit testing (depending on what you are planning to do) may be to pre-transform your geometry and objects so they are in the dimensions you are viewing them at.

Hope that helps.

Read more comments on GitHub >

github_iconTop Results From Across the Web

HitTest is buggy / not accurate when the UserControl's ...
HitTest is buggy / not accurate when the UserControl's RenderTransform set to a large scale(ScaleX = ScaleY = 500).
Read more >
Incorrect hit testing on transformed Path - wpf
Input hit testing yields incorrect results on a Path element with large scaling factors in its RenderTransform property. The following XAML ...
Read more >
Wpewaf.com
HitTest is buggy / not accurate when the UserControl's RenderTransform set to a large scale (ScaleX = ScaleY = 500) Investigate.
Read more >
Wpewaf.com
HitTest is buggy / not accurate when the UserControl's RenderTransform set to a large scale (ScaleX = ScaleY = 500) Investigate.
Read more >
Wpewaf.com
HitTest is buggy / not accurate when the UserControl's RenderTransform set to a large scale (ScaleX = ScaleY = 500) Investigate. Create a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found