Остановите инерцию System.Windows.Shapes.Rectangle, если в приложении сенсорного экрана WPF произошло столкновение с другой формой. - PullRequest
0 голосов
/ 28 февраля 2019

Я работаю над приложением с сенсорным экраном.Это приложение для определенной отрасли, но общие идеалы - это все, что нужно для объяснения проблемы.Для начала я делаю ускоренный курс по WPF и позволяю пользователю добавить новую команду (Shape - Rectangle), а затем назначит ему функции.Например, они могут добавить один, затем добавить второй, затем третий и т. Д., Расположив их там, где они хотят.

Я хотел бы узнать, как сообщить API о возникновении инерции и сказать пользователюприкасается к фигуре, затем перебрасывает ее по экрану, чтобы событие не только завершилось, когда оно достигает края экрана (уже делает это), но также если оно пересекает или поражает другую фигуру.Ниже приведен общий код для быстрого базового подтверждения концепции.

void Window_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
        try
        {
            // Get the Rectangle and its RenderTransform matrix.
            Rectangle rectToMove = e.OriginalSource as Rectangle;

            Matrix rectsMatrix = ((MatrixTransform)rectToMove.RenderTransform).Matrix;

            // Rotate the Rectangle.
            rectsMatrix.RotateAt(e.DeltaManipulation.Rotation,
                                 e.ManipulationOrigin.X,
                                 e.ManipulationOrigin.Y);

            // Resize the Rectangle.  Keep it square 
            // so use only the X value of Scale.
            rectsMatrix.ScaleAt(e.DeltaManipulation.Scale.X,
                                e.DeltaManipulation.Scale.X,
                                e.ManipulationOrigin.X,
                                e.ManipulationOrigin.Y);

            // Move the Rectangle.
            rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
                                  e.DeltaManipulation.Translation.Y);

            // Apply the changes to the Rectangle.
            rectToMove.RenderTransform = new MatrixTransform(rectsMatrix);

            Rect containingRect =
                new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);

            Rect shapeBounds =
                rectToMove.RenderTransform.TransformBounds(
                    new Rect(rectToMove.RenderSize));

            // Check if the rectangle is completely in the window.
            // If it is not and intertia is occuring, stop the manipulation.
            if (e.IsInertial && !containingRect.Contains(shapeBounds))
            {
                e.Complete();
            }

            if (e.IsInertial)
            {
                //convert current moving rect to new rect drawing type
                var tempRect = new Rect(Canvas.GetLeft(rectToMove), Canvas.GetTop(rectToMove), rectToMove.Width, rectToMove.Height);
                //we need to convert SytsemWindows.Shapes.Rectablge to SystemWindows.Drawing.Rect first
                //List<System.Windows.Shapes.Rectangle> removeCurrent = Commands.Where(r => r != rectToMove).ToList();
                //List<System.Windows.Rect> coordinates = Commands.Where(r => r.Name != rectToMove.Name).Select(r => new Rect(Canvas.GetLeft(r), Canvas.GetTop(r), r.Width, r.Height)).ToList();

                List<System.Windows.Rect> recs = new List<Rect>();

                List<Rectangle> test = Commands.Where(r => r.Name != rectToMove.Name).ToList();

                foreach (System.Windows.Shapes.Rectangle re in test)
                {
                    if (re != rectToMove)
                    {
                        recs.Add(new Rect(Canvas.GetLeft(re), Canvas.GetTop(re), re.Width, re.Height));
                    }
                }

                //if rect item is in motion inertia and it intersects with any of pre made command rects, then stop.
                if (recs.Any(c => c.InteriorIntersectsWith(tempRect)))
                {
                    //There is overlapping
                    e.Complete();
                }

            }

        }
        catch(Exception ex)
        {

        }

        e.Handled = true;
    }

Проблема в том, что инерция работает нормально.После добавления второй фигуры на холст инерция больше не работает.Пользователь может щелкнуть и перетащить их, но при попытке пролистать фигуры они мгновенно останавливаются, как будто он сообщает со всех позиций, что он пересекается с другой формой, даже когда они не находятся рядом друг с другом.Любые идеи о том, что я делаю не так?Example after user has added one or more items, the touch drag and fling breaks

...