WPF mutliselection forms using drag rectangle

I would like to implement multiple selection of shapes using a drag rectangle. I have many forms on canvas: enter image description here

Current shapes are associated with their respective models (MVVMs). My selection rectangle looks like this: enter image description here

When I finished drawing the selection rectangle (mouse event), I run this code:

var itemToSelect = ViewModel.ItemsInCanvas.Where((item) => { // TODO : test each types of shapes to know if the selection rectangle intersects with it }).ToList(); 

I have different types of object models for shapes:

  • Quadrangle: I can get (in code) the coordinates of each of the four points.
  • Triangle: I can get (in code) the coordinates of each of three points.
  • Curve: I can get the path data (as a string).
  • Lin: I can get two points (sinusoidal same object)
  • Circle: I can get the height and width.

I can also get the top and left parts of each shape.

All thoses forms are stored in a list in my main view model: ItemsInCanvas

When I enter the code above, I would like to check each element to see if they intersect with the selection rectangle (whose I know the coordinates).

My first attempt was (only for a curve element):

 var itemToSelect = ViewModel.ItemsInCanvas.Where((item) => { if (item is CurveItem) { // I got my Curve Item CurveItem curveItem = (item as CurveItem); // I got the selection rectangle RectangleGeometry SelectionRectangleGeometry = new RectangleGeometry(SelectionRectangle); // Is the rectangle intersecting the shape ? if (SelectionRectangleGeometry.FillContainsWithDetail(Geometry.Parse(curveItem.Data)) == IntersectionDetail.Intersects) return true; } }).ToList(); 

But it does not work, the test returns the same thing: crosses.

I think the test does not care about the position of each figure (for example, if it was absolute, not relative).

Do you know how I can perform my tests?

+4
source share
1 answer

You could solve this problem by running hit test geometry at a visual level. Pass your canvas and selection geometry to the method shown below, which returns a list of all the shapes that fit into the geometry.

 private IList<Shape> GetSelectedShapes(UIElement element, Geometry geometry) { var shapes = new List<Shape>(); VisualTreeHelper.HitTest(element, null, result => { var shape = result.VisualHit as Shape; if (shape != null) { shapes.Add(shape); } return HitTestResultBehavior.Continue; }, new GeometryHitTestParameters(geometry)); return shapes; } 

You can start reading hit testing in the visual layer .

+2
source

Source: https://habr.com/ru/post/1483809/


All Articles