2

My application consists of a canvas with some user drag-droppable UIelements which can be further connected using lines.

To connect two UIelements I have used a Path consisting a GeometryGroup, which further contains LineGeometry as its childs. Check this screenshot.

So as in the picture, the three items are connected via a Path which consists of 2 LineGeometry. I'm trying to implement 'Remove Link' option but all i can do is remove the whole Path, which would remove both the LineGeometry. How can i specifically select that particular line segment and remove it?

Il Vic
  • 5,576
  • 4
  • 26
  • 37
boop_the_snoot
  • 3,209
  • 4
  • 33
  • 44

2 Answers2

1

There is a solution without implementing math for hit testing. For example if you want to remove a line by mouse down:

<Canvas Mouse.MouseDown="Canvas_MouseDown">

where Canvas_MouseDown should be implemented like this:

private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
    var canvas = sender as Canvas;
    if (canvas == null)
        return;

    // 1. Find a Path containing links

    HitTestResult hitTestResult = VisualTreeHelper.HitTest(canvas, e.GetPosition(canvas));
    var path = hitTestResult.VisualHit as Path;
    if (path == null)
        return;

    // 2. Iterate through geometries of the Path and hit test each one
    //    to find a line to delete

    var geometryGroup = path.Data as GeometryGroup;
    if (geometryGroup == null)
        return;

    GeometryCollection geometries = geometryGroup.Children;
    Point point = e.GetPosition(path);
    var pen = new Pen(path.Stroke, path.StrokeThickness);

    var lineToDelete = geometries.OfType<LineGeometry>()
                                 .FirstOrDefault(l => l.StrokeContains(pen, point));

    // 3. Delete link

    if (lineToDelete != null)
        geometries.Remove(lineToDelete);
}
Maxim
  • 1,995
  • 1
  • 19
  • 24
-1

You need the distances to the click point.

public void RemoveLink(Point point)
{
    // ...

    // point - 2D click point
    // lineList - list of links (lines)
    setDistance(lineList, point)

    lineList.Sort(compare);
    lineList[0].remove();
    // ...
}

private static Comparison<GeomObject> compare = new Comparison<GeomObject>(GeomObject.CompareByDistance);

public static int CompareByDistance(GeomObject go1, GeomObject go2)
{
    return go1.mDistance.CompareTo(go2.mDistance);
}

private void setDistance(List<Line> lineList, Point point) {
    // set mDistance for each Line
    // mDistance - distance to point
}
Tom Henn
  • 125
  • 6