Как сделать так, чтобы ограничить область перетаскивания изображения в приложении?
Сейчас я занимаюсь разработкой приложения для работы с фотографиями (Windows Phone 8.1 Runtime), но у меня возникла проблема в том, что не нужно было ограничивать область перетаскивания изображений во время масштабирования фотографий.
Здесь ниже код:
<Canvas Name="zoomgrid" Visibility="Collapsed">
<Image x:Name="zoomimages"
Stretch="Fill"
Width="480"
Height="800"
ManipulationDelta="img_intro_ManipulationDelta"
RenderTransformOrigin="0.5,0.5"
ManipulationMode="All">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
</Canvas>
double mincale = 0.5;
double maxscale = 10.0;
private void Image_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
Image elemt = sender as Image;
CompositeTransform transform = elemt.RenderTransform as CompositeTransform;
transform.ScaleX *= e.Delta.Scale;
transform.ScaleY *= e.Delta.Scale;
transform.TranslateX += e.Delta.Translation.X;
transform.TranslateY += e.Delta.Translation.Y;
if (transform.ScaleX < mincale) transform.ScaleX = mincale;
if (transform.ScaleY < mincale) transform.ScaleY = mincale;
if (transform.ScaleX > maxscale) transform.ScaleX = maxscale;
if (transform.ScaleY > maxscale) transform.ScaleY = maxscale;
//To limit the images dragging but did not success.
double scalewidth = Zoomimages.ActualWidth * ct.ScaleX;
double scleheight = Zoomimages.ActualHeight * ct.ScaleY;
double xdiff = Math.Max(0, (scalewidth - this.content.ActualWidth) / 2);
double ydiff = Math.Max(0, (scleheight - this.content.ActualHeight) / 2);
if (Math.Abs(ct.TranslateX) > xdiff)
ct.TranslateX = xdiff * Math.Sign(e.Delta.Translation.X);
if (Math.Abs(ct.TranslateY) > ydiff)
ct.TranslateY = ydiff * Math.Sign(e.Delta.Translation.Y);
}
1 ответ
Я добился этого с помощью вспомогательного метода, чтобы проверить, находится ли изображение в настоящее время в границах другого элемента.
В вашем случае элемент, который вы хотите проверить, это изображение, и вы хотите проверить, что оно находится в пределах холста.
private bool IsElementVisible(FrameworkElement element, FrameworkElement container)
{
if (!element.IsVisible)
return false;
Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
if (rect.Left > bounds.Right || rect.Right < bounds.Left || rect.Bottom < bounds.Top || rect.Top > bounds.Bottom)
{
return false;
}
return true;
}
В моем случае я использовал MatrixTransform вместо CompositeTransform, но метод должен быть таким же.
Я обычно создаю обработчики для "ManipulationStarting" и "ManipulationCompleted", где:
ManipulationStarting:
- Сохраняет текущую (перед манипуляцией) копию Transform.
ManipulationCompleted:
- Проверьте, не выходит ли изображение за границы (используя метод, который я разместил).
- Если выходит за пределы, вернитесь к исходному Transform.
Таким образом, даже если ваше изображение перетаскивается из поля зрения, как только пользователь поднимает палец, изображение возвращается к последнему удачному местоположению.
Если вас интересует более широкий контекст, в котором я использовал этот код, у меня есть поведение WPF, которое включает в себя все эти функции. Код находится на Codeplex. Этот класс может быть интересен для вас.
Надеюсь, это поможет:)