WPF快照网格的实现
我正在尝试使用WPF和画布实现一个快照网格。我认为我的数学是关闭的,因为UIElement不会捕捉到背景中的网格。下面是我用来创建网格的xaml,以及我用来尝试将UIElement捕捉到最近的网格线的方法。一旦触发鼠标按钮向上事件,将立即触发所使用的方法。如果这不是WPF的正确方法,有人能给我指出正确的方向吗 XAMLWPF快照网格的实现,wpf,xaml,Wpf,Xaml,我正在尝试使用WPF和画布实现一个快照网格。我认为我的数学是关闭的,因为UIElement不会捕捉到背景中的网格。下面是我用来创建网格的xaml,以及我用来尝试将UIElement捕捉到最近的网格线的方法。一旦触发鼠标按钮向上事件,将立即触发所使用的方法。如果这不是WPF的正确方法,有人能给我指出正确的方向吗 XAML Canvas.GetLeft(element)将返回一个double,因此即使gridWidth是一个整数,它将执行双精度算术,并且除法和乘法将或多或少地抵消。我想你想做以下一件
Canvas.GetLeft(element)
将返回一个double,因此即使gridWidth
是一个整数,它将执行双精度算术,并且除法和乘法将或多或少地抵消。我想你想做以下一件事:
double xSnap = Math.Floor(Canvas.GetLeft(element) / gridWidth) * gridWidth;
double xSnap = Math.Ceiling(Canvas.GetLeft(element) / gridWidth) * gridWidth;
double xSnap = Math.Round(Canvas.GetLeft(element) / gridWidth) * gridWidth;
这些函数将除法结果四舍五入为整数,并返回gridWidth的倍数 你的问题是你的函数实际上什么都不做。你除以网格大小,然后乘以网格大小,所以实际上你什么都没做(2*16/16=2)。您需要使用的是模数
%
操作符,并根据与网格大小的距离调整x/y位置
这是一个工作函数,如果更靠近左/顶轴网线,则捕捉左/顶轴网线,否则捕捉右/下轴网线:
private void SnapToGrid(UIElement){
double xSnap=Canvas.GetLeft(元素)%GRID\u SIZE;
double ySnap=Canvas.GetTop(元素)%网格大小;
//如果小于网格大小的一半,则向左/向上捕捉
//(减去余数),
//否则,将其向右/向下移动网格大小的剩余距离
//(通过将剩余距离添加到下一个栅格点)。
如果(xSnap的想法是确保任何对象的位置限制在某个数字集内;即,最终位置应四舍五入,并在该集合内
集合由任意数字的所有因素组成,j
;j
控制“捕捉”的强度,并确定出现在集合中的数字。新位置也必须只包含出现在集合中的数字
例如,假设对象的原始位置是(5,0)
,我们希望将其移动到(16,23)
。让我们继续拍摄5:这意味着对象的位置可能只包含5的因子。原始位置已落在此集中,但新位置不在其中
为了模拟“捕捉”,新位置必须落在(15,20)
或(20,25)
上。找到最接近的16和23的因子将给出正确的点。在大多数情况下,有必要对结果进行四舍五入
示例
//Get original point of object relative to container element
var original_point = e.GetPosition(sender);
//Calculate new x and y position based on mouse
//var new_x = ...
//var new_y = ...
//New position must be multiple of 8
var snap = 8;
//Get nearest factor of result position
new_x = original_point.X.NearestFactor(snap);
new_y = original_point.Y.NearestFactor(snap);
public static double NearestFactor(this double Value, double Factor)
{
return Math.Round((Value / Factor), MidpointRounding.AwayFromZero) * Factor;
}
不用说,在调整对象大小时也可以使用此算法,以确保对象的位置和大小“捕捉”
double xSnap = Math.Floor(Canvas.GetLeft(element) / gridWidth) * gridWidth;
double xSnap = Math.Ceiling(Canvas.GetLeft(element) / gridWidth) * gridWidth;
double xSnap = Math.Round(Canvas.GetLeft(element) / gridWidth) * gridWidth;
//Get original point of object relative to container element
var original_point = e.GetPosition(sender);
//Calculate new x and y position based on mouse
//var new_x = ...
//var new_y = ...
//New position must be multiple of 8
var snap = 8;
//Get nearest factor of result position
new_x = original_point.X.NearestFactor(snap);
new_y = original_point.Y.NearestFactor(snap);
public static double NearestFactor(this double Value, double Factor)
{
return Math.Round((Value / Factor), MidpointRounding.AwayFromZero) * Factor;
}