0

I'm creating a CAD program in WPF that adds and deletes lines and rectangles, both of which are described by a PathGeometry. When I get further along with the program, it will contain a great variety of different PathGeometries, each of which make up the property of individual DrawingVisuals. I'm using the Visual class for performance reasons.

Since each DrawingVisual is virtually identical, because all it is is just a DrawingVisual made up a PathGeometry, it has no unique identifier. I need an identifier of some sort so that when I right-click on a line or rectangle I can draw some handles on it to make it modifiable using the mouse. (I want the end-points of the line to be moveable, the rectangle to be stretchable, etc.) There are examples on line of handles on Lines, Bezier curves, etc. but they don't deal with the issue of having different types.

In the below code, which is just like mine, the clicking of the mouse retrieves the drawingVisual object. But, since drawingVisuals don't have any special feature on them that says, "This is a rectangle" or "This is a line", I need to figure out a way of getting that information from the HitTestResult result. Knowing that, I can determine how to treat it when I want to modify it. A line is going to have 2 control points, a rectangle is going to have 4, and some of my other (not yet made yet) geometries will have 6 or more control values.

When I go to the visualTree in debugging mode (accessed by Debug>Window) all it says is "DrawingVisual". That's not enough information to know how to treat it as a line or a rectangle.

So, on big-wig CAD programs, they allow you to modify the object that you have clicked on. The software has some way of knowing what you clicked on, and I'd like to have that feature on my beginner-level CAD program.

I tried using the debug feature and looking for some sort of unique identifier, but couldn't find one. I thought about using a List and giving each item as it's created, but I have no way of linking it with the HitTestResult result.

It can be done, so that isn't an issue, but I need a scheme for imitating how CAD programs accomplish this feature.

private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // Retrieve the coordinate of the mouse position.
    Point pt = e.GetPosition((UIElement)sender);

    HitTestResult result = VisualTreeHelper.HitTest(myCanvas, pt);

    if (result != null)
    {
        // Perform action on hit visual object.
    }
}

Any help in telling me how to go about it would be appreciated. Basically, what is the scheme that high-feature CAD programs use to track what type of Visual the mouse has clicked on?

TYIA

smn.tino
  • 2,272
  • 4
  • 32
  • 41
  • Check the DrawingVisual's [Drawing](https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.drawingvisual.drawing?view=netframework-4.7.2#System_Windows_Media_DrawingVisual_Drawing) property. There should be a GeometryDrawing with your Geometry. That said, using Visuals seems to be overly complicated here. I'm sure you could as well use Path elements. – Clemens Jul 28 '18 at 21:47
  • I am able to extract that GeometryDrawing, but how will that help? I still can't tell if I'm over a rectangle or a line. Should I parse it or something, and that will tell me? Like, if the LineGeometry has a length of 20 bytes, and the Rectangle is 40 bytes? I might run into problems if two types end up with the same number of bytes, (which wouldn't apply to Line or Rect obviously, but for another Geometry when other designs get added. Too bad there isn't some way of going into the DrawingVisual code and adding a property to it. Like Visual.Line or Visual.Rect. – SojourningStudent Jul 28 '18 at 22:53
  • You would then *of course* check if the GeometryDrawing's `Geometry` property holds a RectangleGeometry or something else (by using the `is` or `as` operator). Seriously, you should consider a more simple approach. – Clemens Jul 28 '18 at 22:55
  • OK. I chose DrawingVisual because of speed. A lot of stuff is going to move on the screen when it's all done. It's going to be like an animated painting. Everything is a PathGeometry at its core. So, if I have a complicated shape, say a human figure for one DrawingVisual, and a star figure for another, I still need to distinguish the two. DrawingVisual was selected for speed, but what other approaches do you have in mind? – SojourningStudent Jul 28 '18 at 23:04
  • As already said, Path elements. You can bind their Data property to a Geometry property of a view model class, and organize them in ItemsControls. You shouldn't optimize for speed until you have a serious performance problem. – Clemens Jul 28 '18 at 23:24
  • Ok. I'll go that route. – SojourningStudent Jul 29 '18 at 01:08

0 Answers0