В WPF у меня есть сетка, содержащая часть содержимого, с которой мне нужно манипулировать, используя два жестов пальца. Приведенный ниже код отлично подходит для перемещения и масштабирования, но мне нужно знать, как ограничить максимальные и минимальные значения масштабирования, например, от 100% до 200% увеличения. Также мне нужно ограничить перемещение содержимого, чтобы он оставался в пределах размера контейнера сетки.
Код пока:
Private Sub gridLeft_ManipulationStarting (отправитель как объект, e As ManipulationStartingEventArgs) обрабатывает gridLeft.ManipulationStarting
e.ManipulationContainer = gridMapHolderLeft
e.Mode = ManipulationModes.Scale + ManipulationModes.Translate
e.Handled = True
MyBase.OnManipulationStarting(e)
End Sub
Private Sub gridLeft_ManipulationDelta (отправитель как объект, e As ManipulationDeltaEventArgs) обрабатывает gridLeft.ManipulationDelta
Dim element As UIElement = TryCast(e.Source, UIElement)
Dim xform As MatrixTransform = TryCast(element.RenderTransform, MatrixTransform)
Dim matrix As Matrix = xform.Matrix
Dim delta As ManipulationDelta = e.DeltaManipulation
Dim center As Point = e.ManipulationOrigin
matrix.Translate(-center.X, -center.Y)
matrix.Scale(delta.Scale.X, delta.Scale.Y)
matrix.Translate(center.X, center.Y)
matrix.Translate(delta.Translation.X, delta.Translation.Y)
xform.Matrix = matrix
e.Handled = True
MyBase.OnManipulationDelta(e)
End Sub
Вы можете ограничить масштаб, проверив полученную матрицу. Определяющее значение ПОСЛЕ того, как вы применили масштабирование. Если значение больше вашего максимума или меньше минимальных значений шкалы, вы можете просто вернуться из Sub до применения матрицы.
В этом примере минимум не масштабируется (1.0), а максимальная - 2x шкала (2.0).
(Извините мой код VB - я разработчик С# 99,9% времени!)
Private Sub gridLeft_ManipulationDelta(sender As Object, e As ManipulationDeltaEventArgs) Handles gridLeft.ManipulationDelta
Dim element As UIElement = TryCast(e.Source, UIElement)
Dim xform As MatrixTransform = TryCast(element.RenderTransform, MatrixTransform)
Dim matrix As Matrix = xform.Matrix
Dim delta As ManipulationDelta = e.DeltaManipulation
Dim center As Point = e.ManipulationOrigin
matrix.Translate(-center.X, -center.Y)
matrix.Scale(delta.Scale.X, delta.Scale.Y)
matrix.Translate(center.X, center.Y)
matrix.Translate(delta.Translation.X, delta.Translation.Y)
If matrix.Determinant >= 2.0 Or matrix.Determinant <= 1.0 Then
Return
End If
xform.Matrix = matrix
e.Handled = True
MyBase.OnManipulationDelta(e)
End Sub
Я в середине пути рефакторинг поведения WPF, который обеспечивает только эти функции. Это написано на С#, а не VB, но просмотр исходного кода может вас заинтересовать. В частности, код в методе ManipulationDeltaHandler.
Там также код, чтобы проверить границы масштабированного элемента на его элемент контейнера, чтобы предотвратить выталкивание или масштабирование материала вне поля зрения.
В итоге я написал это поведение, поскольку TranslateZoomRotateBehavior, предоставленный Microsoft, просто не делает того, что нам нужно.
Надеюсь, там что-то помогает.