I'm working on a simple drawing app to further advance my skills and I can't seem to开发者_JAVA技巧 get the logic down for an eraser tool. The app simply uses the Line class to create lines as the user moves their finger. For the eraser tool I tried using the VisualTreeHelper as follows:
List<UIElement> elements = (List<UIElement>)VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(tree), ContentPanelCanvas);
foreach (UIElement element in elements)
{
if (element is Line)
{
this.ContentPanelCanvas.Children.Remove(element);
}
}
It at some points but can be very slow and laggy. Sometimes I would have to touch the area more than 5 times to get rid of the line there.
Is there an alternative to this?
The e.GetPosition(tree)
will be returning a point. Try instead using a Rect
with the position as its center.
const double fingerMargin = 10.0;
Point p = e.GetPosition(tree);
Rect r = new Rect(p.X - fingerMargin, p.Y - fingerMargin, fingerMargin * 2, fingerMargin * 2);
var elements = VisualTreeHelper.FindElementsInHostCoordinates(r, ContentPanelCanvas);
Line lineToRemove = elements.OfType<Line>().FirstOrDefault();
if (lineToRemove != null)
{
ContentPanelCanvas.Children.Remove(lineToRemove);
}
Note don't cast the result of FindElementsInHostCoordinates to List<T>
, that is an implementation detail, the documentation only guarantees it to be an IEnumerable<UIElement>
, besides which it is an unnecessary cast.
You are actually looking for the set of elements that match the hit test of a single pixel. If your lines are narrow, then it's like a needle in a haystack; it's very hard to hit the line precisely to remove it.
Instead you need to use a fuzzy match using a rectangle instead of a point. You can use the same API, just the rectangle version of it:
- VisualTreeHelper.FindElementsInHostCoordinates Method (Rect, UIElement)
VisualTreeHelper.FindElementsInHostCoordinates(r, MainCanvas); Is not returning any Elements.
精彩评论