且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-10-19 15:49:58

我想出了一个很好玩的方法!

I figured out a nice and fun way!

我在 MouseUp 事件中计算出鼠标在网格上的位置,然后计算出鼠标在控件上的相对位置,因为它跨越了几行/列.

I worked out the position on the grid that the the mouse is on on the MouseUp event and then the relative position of the mouse on the control since it spans several rows/columns.

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++;
        }
    }

然后我从正常位置中删除相对位置,这样当你放下它时,它总是落在屏幕的左上角.当我移动我的控件时,我使用边距来移动它,这会在当时的网格上拧紧位置,如下所示:

I then take away the relative positions from the normal positions so that when you drop it, it always drops on the top left of the screen. When I move my controls, I use margins to move it, which screws up the position on the grid at the time, as shown below:

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;
    }

为了解决这个问题,我简单地重置了边距.

To tackle this, I simply reset the margin.

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

我希望这对其他人有所帮助,因为我很难找到答案,最后我设法获得了很多关于如何做事的小片段,并最终想出了我自己的解决方案.

I hope this helps someone else since it was rather frustrating for me to find the answer and in the end I managed to get lots of little fragments of how to do things and eventually came up with my own solution.