C# 在WPF中网格中的单元格之间拖放自定义控件
我有一些自定义控件,它们被动态添加到自定义网格中。这些控件可以跨多个列和行(大小都相同)。我想在行和列之间拖放。我可以拖动单个控件,但它们可以无限制地移动到任何地方。甚至在电网之外。我希望这样做,以便它只能在网格内拖动,并捕捉到它拖动到的列/行 有什么简单的方法可以做到这一点吗 老实说,如果我能得到当前结束的行/列,那么我所需要做的就是将它的列/行设置为它们,这可能会做到,然后只需要担心将它保留在网格中 有什么简单的方法可以做到这一点吗 我想说,这个问题的答案在很大程度上取决于您使用拖放功能的经验。。。对于初学者来说,我会说答案是否定的,但是对于一些有经验和常识的人来说,这可能并不太糟糕 要确定用户的鼠标在哪个网格上,不能直接向前移动。您可以处理C# 在WPF中网格中的单元格之间拖放自定义控件,c#,wpf,drag-and-drop,grid,C#,Wpf,Drag And Drop,Grid,我有一些自定义控件,它们被动态添加到自定义网格中。这些控件可以跨多个列和行(大小都相同)。我想在行和列之间拖放。我可以拖动单个控件,但它们可以无限制地移动到任何地方。甚至在电网之外。我希望这样做,以便它只能在网格内拖动,并捕捉到它拖动到的列/行 有什么简单的方法可以做到这一点吗 老实说,如果我能得到当前结束的行/列,那么我所需要做的就是将它的列/行设置为它们,这可能会做到,然后只需要担心将它保留在网格中 有什么简单的方法可以做到这一点吗 我想说,这个问题的答案在很大程度上取决于您使用拖放功能的经
PreviewDragOver
事件,并使用检查鼠标当前位于哪个控件上:
private void PreviewDragOver(object sender, DragEventArgs e)
{
HitTestResult hitTestResult = VisualTreeHelper.HitTest(adornedUIElement,
e.GetPosition(adornedUIElement));
Control controlUnderMouse = hitTestResult.VisualHit.GetParentOfType<Control>();
}
当然,一旦在鼠标下的
controlUnderMouse
变量中有了Control
,在到达网格之前,在通过UIElement
时,您仍然需要做大量的工作。。。当然,您可以进一步使用GetParentOfType
方法来简化您的工作。我想出了一个有趣的方法
我计算出鼠标在MouseUp事件上的网格位置,然后计算出鼠标在控件上的相对位置,因为它跨越多行/列
public void getPosition(UIElement element, out int col, out int row)
{
DControl control = parent as DControl;
var point = Mouse.GetPosition(element);
row = 0;
col = 0;
double accumulatedHeight = 0.0;
double accumulatedWidth = 0.0;
// calc row mouse was over
foreach (var rowDefinition in control.RowDefinitions)
{
accumulatedHeight += rowDefinition.ActualHeight;
if (accumulatedHeight >= point.Y)
break;
row++;
}
// calc col mouse was over
foreach (var columnDefinition in control.ColumnDefinitions)
{
accumulatedWidth += columnDefinition.ActualWidth;
if (accumulatedWidth >= point.X)
break;
col++;
}
}
然后我将相对位置从正常位置移开,这样当你放下它时,它总是落在屏幕的左上角。当我移动控件时,我会使用边距来移动它,这会在当时扭曲网格上的位置,如下所示:
void Chart_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (IsMouseCaptured)
{
Point mouseDelta = Mouse.GetPosition(this);
mouseDelta.Offset(-mouseOffset.X, -mouseOffset.Y);
Margin = new Thickness(
Margin.Left + mouseDelta.X,
Margin.Top + mouseDelta.Y,
Margin.Right - mouseDelta.X,
Margin.Bottom - mouseDelta.Y);
}
}
void Chart_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
mouseOffset = Mouse.GetPosition(this);
CaptureMouse();
parent.currentObject = this;
}
为了解决这个问题,我只需重新设置保证金
public void updatePosition()
{
Grid.SetRow(this, (int)position.Y);
Grid.SetColumn(this, (int)position.X);
Margin = new Thickness();
}
我希望这对其他人有所帮助,因为找到答案对我来说是相当令人沮丧的,最终我设法获得了很多关于如何做事的小片段,并最终提出了自己的解决方案 可能是这样的:?不过它们是任意的控件。虽然它们都是从同一事物中派生出来的。我需要更多信息,以便查看我将项目拖动到的行/列。我通过计算行高+列宽,直到鼠标到达鼠标点,从而获得鼠标在当前网格上的位置。然后,我计算出鼠标相对于控件左上角的相对位置,并将其从位置上取下,以便它将其指定给该位置。它得到了正确的值,但当我对项执行Grid.SetRow(this,row)
操作时,同样地,使用Grid.SetColumn
时,它会将它们放在一个随机位置。有什么原因吗?是因为它使用边距移动控件吗?嗯,是的。当我更新它们时,我重置了边距,效果非常好!我不知道为什么我要评论这个答案,因为我没有使用它的任何东西,但无论如何谢谢你的帮助!我不知道我为什么要评论这个答案。。。我也一样。将你的解决方案添加到答案中,并在可能的情况下接受它。对此表示抱歉!我已经这样做了,但不幸的是,我有几天不能接受它。WPFThumbControl
应该能够在没有Margin
技巧的情况下处理这个问题,但它不能。“在使用ThumbControl
s进行了无数个毫无结果的小时后,我终于走上了你的路,@Gentatsu。干得好,干得好。parent
指的是什么?什么是DControl
?您可以发布整个代码吗?在复制上有困难。
public void updatePosition()
{
Grid.SetRow(this, (int)position.Y);
Grid.SetColumn(this, (int)position.X);
Margin = new Thickness();
}