DataGridView拖放 - 限制为“bar”而不是单元格

时间:2011-11-23 13:39:11

标签: c# winforms datagridview drag-and-drop

我有一个DataGridView,我允许用户拖放行来重新排序它们。这样工作正常,但它似乎非常敏感 - 单击单元格时单击并轻轻移动鼠标即可开始拖放操作。

所以我想做的只是允许从DataGridView的“侧栏”拖放 - 即下图中红线左侧的“列”:

enter image description here

这可能吗?这是我的代码:

[code]

    private Rectangle dragBoxFromMouseDown;
    private int rowIndexFromMouseDown;
    private int rowIndexOfItemUnderMouseToDrop;

    private void grdCons_MouseMove(object sender, MouseEventArgs e)
    {
        if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
        {
            if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(e.X, e.Y))
            {
                DragDropEffects dropEffect = grdCons.DoDragDrop(grdCons.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
            }
        }
    }

    private void grdCons_MouseDown(object sender, MouseEventArgs e)
    {
        rowIndexFromMouseDown = grdCons.HitTest(e.X, e.Y).RowIndex;
        if (rowIndexFromMouseDown != -1)
        {
            Size dragSize = SystemInformation.DragSize;
            dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
        }
        else
        {
            dragBoxFromMouseDown = Rectangle.Empty;
        }
    }

    private void grdCons_DragOver(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Move;
    }

    private void grdCons_DragDrop(object sender, DragEventArgs e)
    {
        Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
        rowIndexOfItemUnderMouseToDrop = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

        if (e.Effect == DragDropEffects.Move)
        {
            DataGridViewRow rowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
            grdCons.Rows.RemoveAt(rowIndexFromMouseDown);
            grdCons.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);
        }
    }

[/代码]

1 个答案:

答案 0 :(得分:1)

我设法通过检查MouseDown事件处理程序中的DataGridViewHitTestType来使用行标题来实现拖放操作,如下所示:

private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
    // Get the index of the item the mouse is below.
    rowIndexFromMouseDown = dataGridView1.HitTest(e.X, e.Y).RowIndex;

    // Here we also check that the HitTest happened on a RowHeader
    if (rowIndexFromMouseDown != -1 && (dataGridView1.HitTest(e.X, e.Y).Type == DataGridViewHitTestType.RowHeader))
    {
        // Remember the point where the mouse down occurred. 
     // The DragSize indicates the size that the mouse can move 
     // before a drag event should be started.                
        Size dragSize = SystemInformation.DragSize;

        // Create a rectangle using the DragSize, with the mouse position being
        // at the center of the rectangle.
        dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2),
                                                       e.Y - (dragSize.Height / 2)),
                            dragSize);
    }
    else
        // Reset the rectangle if the mouse is not over an item in the ListBox.
        dragBoxFromMouseDown = Rectangle.Empty;
}

我猜你从DataGridView FAQ获得了你的代码,因为你的代码几乎与那里的例子相同?

如果你没有,那么我建议你看一下常见问题解答 - 这里有很多很好的建议和例子。