在 WPF 中的网格中的单元格之间拖放自定义控件

Gen*_*tsu 5 c# wpf grid drag-and-drop

我有一些动态添加到自定义网格的自定义控件。这些控件可以跨越多个列和行(它们的大小都相同)。我想在行和列之间拖放。我可以拖动单个控件,但它们可以不受限制地移动到任何地方。甚至离网。我想这样做,所以它只能在网格内拖动并捕捉到它拖动到的列/行。

有没有什么简单的方法可以做到这一点?

老实说,如果我能得到它结束的当前行/列,那么我需要做的就是将它的列/行设置为它们,这可能会做到,然后只需担心将其保留在网格内。

Gen*_*tsu 5

我想出了一个又好又有趣的方法!

我计算出鼠标在 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++;
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后,我将相对位置从正常位置移开,这样当您放下它时,它总是落在屏幕的左上角。当我移动控件时,我使用边距来移动它,这会搞乱当时网格上的位置,如下所示:

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;
    }
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我只需重置边距即可。

public void updatePosition()
    {
        Grid.SetRow(this, (int)position.Y);
        Grid.SetColumn(this, (int)position.X);
        Margin = new Thickness();
    }
Run Code Online (Sandbox Code Playgroud)

我希望这对其他人有帮助,因为找到答案对我来说相当令人沮丧,最后我设法获得了很多关于如何做事的小片段,并最终提出了我自己的解决方案。