Перетаскивание Silverlight DeepZoom позволяет перетаскивать MultiScaleImage за пределы экрана - PullRequest
0 голосов
/ 18 июня 2010

У меня какая-то проблема, и я надеюсь, что кто-то может ответить на вопрос. У меня есть проект Deep Zoom, в котором я использовал стандартный проект (Deep Zoom Composer), который помещает поведение DeepZommInitializer в элемент управления MultiScaleImage. Я пытаюсь ограничить перетаскивание, чтобы убедиться, что пользователь не перетаскивает изображение за пределы экрана (и поэтому не может найти изображение). Я добавил кнопку «Домой», которая вернет изображение в исходное местоположение при увеличении 1. Во всяком случае, вот код, который у меня есть на данный момент (поиск в Интернете в поисках ответа).

        // msi is the multiscale image
        msi.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
        {
            lastMouseDownPos = e.GetPosition(msi); // class level var
            lastMouseViewPort = msi.ViewportOrigin; // class level var

            mouseDown = true; // class level var

            msi.CaptureMouse();
        };

        msi.MouseMove += delegate(object sender, MouseEventArgs e)
        {
            lastMousePos = e.GetPosition(msi);

            if (duringDrag) 
            {
                Point newPoint = lastMouseViewPort;

                newPoint.X += (lastMouseDownPos.X - lastMousePos.X) / msi.ActualWidth * msi.ViewportWidth;
                newPoint.Y += (lastMouseDownPos.Y - lastMousePos.Y) / msi.ActualWidth * msi.ViewportWidth;

                var limits = new Rect(new Point(1, 1 / msi.AspectRatio), new Point(-1, -1 / msi.AspectRatio));

                if (newPoint.X > limits.Right * .999)
                {
                    newPoint.X += (-2 * (lastMouseDownPos.X - lastMousePos.X)) / msi.ActualWidth * msi.ViewportWidth; // Reverses direction when going off left

                }

                if (newPoint.Y > limits.Bottom * .999)
                {
                    newPoint.Y += (-2 * (lastMouseDownPos.Y - lastMousePos.Y)) / msi.ActualWidth * msi.ViewportWidth; // Reverses direction when going off top of screen
                }

                msi.ViewportOrigin = lastMouseViewPort = newPoint;
                lastMouseDownPos = lastMousePos;
            }
        };

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

Ответы [ 2 ]

0 голосов
/ 08 апреля 2011

Полагаю, следующий код правильно определяет, оставляет ли ViewportOrigin некоторую часть изображения на экране. (ImageCtrl - переменная класса для MultiScaleImage).

    private bool IsValidOrigin(Point point)
{
  var limits = new Rect(
                 new Point(-0.95 * ImageCtrl.ViewportWidth, -0.85 * ImageCtrl.ViewportWidth/ ImageCtrl.AspectRatio), 
                 new Point(0.95, 0.85/ImageCtrl.AspectRatio));
  return limits.Contains(point);
}
0 голосов
/ 18 июня 2010

И вот так я сам понял (наконец, через несколько недель).

Вот ответ (просто измените событие перемещения мыши следующим образом):

        msi.MouseMove += delegate(object sender, MouseEventArgs e)
        {
            lastMousePos = e.GetPosition(msi);

            if (duringDrag) 
            {
                Point newPoint = lastMouseViewPort;

                newPoint.X += (lastMouseDownPos.X - lastMousePos.X) / msi.ActualWidth * msi.ViewportWidth;
                newPoint.Y += (lastMouseDownPos.Y - lastMousePos.Y) / msi.ActualWidth * msi.ViewportWidth;
                var limits = new Rect(new Point(1, 1 / msi.AspectRatio), new Point(-1 / Settings.ZoomLevel, -1 / msi.AspectRatio / Settings.ZoomLevel));

                if (newPoint.X < limits.Left * .999)
                {
                    newPoint.X += (-2*(lastMouseDownPos.X - lastMousePos.X)) / msi.ActualWidth * msi.ViewportWidth;  // we went off right so reverse X direction

                }
                if (newPoint.X > limits.Right * .999)
                {
                    newPoint.X += (-2 * (lastMouseDownPos.X - lastMousePos.X)) / msi.ActualWidth * msi.ViewportWidth; // we went off left so reverse X direction
                }
                if (newPoint.Y < limits.Top * .999)
                {
                    newPoint.Y += (-2*(lastMouseDownPos.Y - lastMousePos.Y)) / msi.ActualWidth * msi.ViewportWidth;  // we went off Bottom so reverse direction
                }
                if (newPoint.Y > limits.Bottom * .999)
                {
                    newPoint.Y += (-2 * (lastMouseDownPos.Y - lastMousePos.Y)) / msi.ActualWidth * msi.ViewportWidth; // we went off Top so reverse direction
                }
                msi.ViewportOrigin = lastMouseViewPort = newPoint;
                lastMouseDownPos = lastMousePos;

                msi.SendMovedZoomMsg(Settings.ZoomLevel, newPoint, myClassName);
            }
        };

Это, вероятно, не полностью ограничивает изображение, но сохраняет его на экране, и, скорее всего, пользователь перестанет пытаться двигаться в неправильном направлении

...