C# 将控件/UI元素限制在屏幕边界内
我有一个C# 将控件/UI元素限制在屏幕边界内,c#,xaml,canvas,windows-store-apps,microsoft-metro,C#,Xaml,Canvas,Windows Store Apps,Microsoft Metro,我有一个Canvas作为我的应用程序的基础,它有几个控件,用户可以使用各自的操作delta来移动、旋转和缩放 问题在于,当用户用手指移动控件时,可能会意外地将控件移出画布或屏幕边界 如何限制这些控件在画布中的移动?您可以检查控件和WinRT XAML工具包中的灵感 总的来说,这是相当基本的。如果不做惯性,可能是这样的: if (x < 0) x = 0; if (x > _canvas.ActualWidth - this.AssociatedObject.ActualWid
Canvas
作为我的应用程序的基础,它有几个控件,用户可以使用各自的操作delta
来移动、旋转和缩放
问题在于,当用户用手指移动控件时,可能会意外地将控件移出画布
或屏幕边界
如何限制这些控件在画布中的移动?您可以检查控件和WinRT XAML工具包中的灵感
总的来说,这是相当基本的。如果不做惯性,可能是这样的:
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;
一旦获得边界矩形-您可以使用其尺寸,而不是操纵对象的实际宽度
/实际高度
和X&Y来确定其可以或不能移动的位置。是,当控件与屏幕边界对齐时,该操作有效。但是,当控件旋转一个角度时,将实际宽度
添加到x
中,其中x是左上角点,不会给出右上角点。
/// <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);
}