user1184598
user1184598

Reputation: 479

Geometry HitTest UIElement in WPF

Is there anyway to hit test an uielement using Geometry in WPF? I tried VisualTreeHelper, but it doesn't work. UIElement could raise mouse down event if a the mouse click on it with a point.

However, I would like to raise an event if a geometry intersect the an UIElement. How could I do so?

public class MyUI : UIElement
{
    protected override void OnReder(DrawingContext dc)
    {
        dc.DrawRectangle(..., new Rect(12,12,120,120));
        ...
    }
}

MyUI ui = new MyUI();
Grid grid = new Grid();
grid.Children.Add(ui);

EllipseGeometry eg = new EllipseGeometry(new Rect(24,24,40,40));

VisualTreeHelper.HitTest(grid, null, HitTestResult, new GeometryHitTestParameters(eg));

if (results.Count > 0)
    MessageBox.Show("Hit Count = "+results.ToString());

...

List<DependencyObject> results;

public HitTestResultBehavior HitTestResult(HitTestResult result)
{
    results.Add(result.VisualHit);
    return HitTestResultBehavior.Continue;
}

Upvotes: 0

Views: 3756

Answers (1)

Clemens
Clemens

Reputation: 128013

Try VisualTreeHelper.HitTest with a GeometryHitTestParameters for the hitTestParameters argument.

Read about Hit Testing in the Visual Layer.

If all you need is a larger sensitive area for mouse input, you might add a transparent shape (e.g. a circle) to your control's visual tree.

EDIT: Your sample code works for me, provided that i add or assume a few things:

First, DrawRectangle in MyUI.OnRender() uses a Brush to fill the rectangle. This could also be a transparent Brush.

dc.DrawRectangle(Brushes.Transparent, null, new Rect(12, 12, 120, 120)); 

Second, results gets initialized somewhere:

private List<DependencyObject> results = new List<DependencyObject>();

Third, the MessageBox displays something sensible:

if (results.Count > 0)
{
   MessageBox.Show(string.Format("Hit Count = {0}", results.Count));
}

Upvotes: 2

Related Questions