1
我有一個Canvas
作爲我的應用程序的基礎,它有幾個控件,用戶可以使用它們各自的ManipulationDelta
's來移動,旋轉和縮放。在屏幕邊界內限制控制/ UIElement
問題是,用戶可能會意外地將控件移出Canvas
或屏幕邊界,同時用手指移動控件。
如何限制這些控件在Canvas
內的移動?
我有一個Canvas
作爲我的應用程序的基礎,它有幾個控件,用戶可以使用它們各自的ManipulationDelta
's來移動,旋轉和縮放。在屏幕邊界內限制控制/ UIElement
問題是,用戶可能會意外地將控件移出Canvas
或屏幕邊界,同時用手指移動控件。
如何限制這些控件在Canvas
內的移動?
您可以在WinRT XAML Toolkit中檢查ToolWindow
控件和FlickBehavior
以獲取靈感。
這是非常基本的整體。如果你不這樣做慣性,可能是這樣的:
if (x < 0)
x = 0;
if (x > _canvas.ActualWidth - this.AssociatedObject.ActualWidth)
x = _canvas.ActualWidth - this.AssociatedObject.ActualWidth;
if (y < 0)
y = 0;
if (y > _canvas.ActualHeight - this.AssociatedObject.ActualHeight)
y = _canvas.ActualHeight - this.AssociatedObject.ActualHeight;
一旦你旋轉或縮放 - 你需要做一些矩陣變換操作,以獲得邊框。幸運的是,該平臺有一些方法可以讓你更容易 - 即TransformToVisual()
和TransformPoint()
方法。我也有一個輔助類,使用en擴展方法,使它更容易 - 檢查出VisualTreeHelperExtensions.GetBoundingRect()
。
/// <summary>
/// Gets the bounding rectangle of a given element
/// relative to a given other element or visual root
/// if relativeTo is null or not specified.
/// </summary>
/// <remarks>
/// Note that the bounding box is calculated based on the corners of the element relative to itself,
/// so e.g. a bounding box of a rotated ellipse will be larger than necessary and in general
/// bounding boxes of elements with transforms applied to them will often be calculated incorrectly.
/// </remarks>
/// <param name="dob">The starting element.</param>
/// <param name="relativeTo">The relative to element.</param>
/// <returns></returns>
/// <exception cref="System.InvalidOperationException">Element not in visual tree.</exception>
public static Rect GetBoundingRect(this FrameworkElement dob, FrameworkElement relativeTo = null)
{
if (DesignMode.DesignModeEnabled)
{
return Rect.Empty;
}
if (relativeTo == null)
{
relativeTo = Window.Current.Content as FrameworkElement;
}
if (relativeTo == null)
{
throw new InvalidOperationException("Element not in visual tree.");
}
if (dob == relativeTo)
{
return new Rect(0, 0, relativeTo.ActualWidth, relativeTo.ActualHeight);
}
var ancestors = dob.GetAncestors().ToArray();
if (!ancestors.Contains(relativeTo))
{
throw new InvalidOperationException("Element not in visual tree.");
}
var topLeft =
dob
.TransformToVisual(relativeTo)
.TransformPoint(new Point());
var topRight =
dob
.TransformToVisual(relativeTo)
.TransformPoint(
new Point(
dob.ActualWidth,
0));
var bottomLeft =
dob
.TransformToVisual(relativeTo)
.TransformPoint(
new Point(
0,
dob.ActualHeight));
var bottomRight =
dob
.TransformToVisual(relativeTo)
.TransformPoint(
new Point(
dob.ActualWidth,
dob.ActualHeight));
var minX = new[] { topLeft.X, topRight.X, bottomLeft.X, bottomRight.X }.Min();
var maxX = new[] { topLeft.X, topRight.X, bottomLeft.X, bottomRight.X }.Max();
var minY = new[] { topLeft.Y, topRight.Y, bottomLeft.Y, bottomRight.Y }.Min();
var maxY = new[] { topLeft.Y, topRight.Y, bottomLeft.Y, bottomRight.Y }.Max();
return new Rect(minX, minY, maxX - minX, maxY - minY);
}
一旦你的邊界RECT - 您可以使用它的尺寸,而不是被操縱的對象ActualWidth
/ActualHeight
和X & y以確定它可以或不可以去。
是的,這是控件與屏幕邊界對齊時的作品。但是,當控件旋轉一個角度時,將'ActualWidth'添加到'x',其中x是左上角的點不會給出右上角的點。 – 2014-09-26 05:16:42
我已經更新了我對這種情況的回答。 – 2014-09-26 15:05:42
這很好! – 2014-09-30 02:44:19