1

我有一个带有 的 WinForm DataGridView,我的目标是拖动一列并将其放在另一列索引上。我知道可以使用AllowUserToOrderColumns = true. 但我必须在 DGV 上执行其他操作。这就是为什么我在鼠标向上事件中需要目标列索引的原因。为此,我使用HitTestInfo

System.Windows.Forms.DataGrid.HitTestInfo myHitTest;
myHitTest = dataGrid1.HitTest(e.X, e.Y);
int p = myHitTest.ColumnIndex;

当我单击第一个 DGV 列时,此代码运行并为我提供列的索引 ( p)。问题是当我将它放在 DGV 的另一列上时,我想知道目标列的索引,使用相同的代码p = -1,我认为是因为HitTestInfo成员返回 a 上的值MouseDown不是a 上的值MouseUp。如果有人能告诉我该怎么做,那就太好了。

4

2 回答 2

2

您可以创建两个 HitTestInfo 对象,一个MouseDownMouseUp.

IMO,您也应该使用DataGridView.HitTestInfo该类,而不是DataGrid.HitTestInfo尝试不调用或命名DataGridViews DataGrids,这与 Control 相似但不同WPF

DataGridView.HitTestInfo myHitTestDown, myHitTestUp;
int visibleColumnDown, visibleColumnUp;

private void dataGrid1_MouseUp(object sender, MouseEventArgs e)
{
    myHitTestUp = dataGrid1.HitTest(e.X, e.Y);
    visibleColumnUp = getVisibleColumn(dataGrid1, e.X);
}

private void dataGrid1_MouseDown(object sender, MouseEventArgs e)
{
    myHitTestDown = dataGrid1.HitTest(e.X, e.Y);
    visibleColumnDown = getVisibleColumn(dataGrid1, e.X);
}

更新:要在列重新排序后查找列的可见索引,只需使用:

dataGrid1.Columns[myHitTestUp.ColumnIndex].DisplayIndex;

在我发现之前,我写了这个小辅助函数,它的作用是一样的:

int getVisibleColumn(DataGridView dgv, int x)
{
    int cx = dgv.RowHeadersWidth;
    int c = 0;
    foreach (DataGridViewColumn col in dgv.Columns)
    {
        cx += col.Width; if ( cx >= x) return c; c++;
    }
    return -1;
}

找出哪个列被洗牌似乎有点困难。有一个事件会为受影响的每一列调用,并且总是首先为被拖动的列调用。这是一种方法:

在类级别创建变量:

List<DataGridViewColumn> shuffled = new List<DataGridViewColumn>();
DataGridViewColumn shuffledColumn = null;

记住第一列:

private void dgvLoadTable_ColumnDisplayIndexChanged(
             object sender, DataGridViewColumnEventArgs e)
{
    if (shuffledColumn == null) shuffledColumn = e.Column;
}

忘记之前发生的事情:

private void dgvLoadTable_MouseDown(object sender, MouseEventArgs e)
{  
    shuffledColumn = null;
}

现在你可以使用它了。然而,选择列并不适合洗牌!如果你这样做

 shuffledColumn.Selected = true;

SelectionMode仅当它是FullColumnSelect或时才会选择它ColumnHeaderSelect- 在任何一种模式下,洗牌都不起作用,恐怕..

于 2014-10-19T11:20:48.663 回答
0

您可以为此使用拖放操作。
假设您有一个Form带有DataGridView命名的dataGridView1.

最初不要忘记允许拖放DataGridView

dataGridView1.AllowDrop = true;

替换所需功能的事件处理程序MouseUp将是dataGridView1_DragDrop,目标列的索引是colIndexOfItemUnderMouseToDrop

private Rectangle dragBoxFromMouseDown;
private int colIndexFromMouseDown;

private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
    if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
    {
        // If the mouse moves outside the rectangle, start the drag.
        if (dragBoxFromMouseDown != Rectangle.Empty &&
            !dragBoxFromMouseDown.Contains(e.X, e.Y))
        {
            // Proceed with the drag and drop, passing in the list item.                    
            dataGridView1.DoDragDrop(colIndexFromMouseDown, DragDropEffects.Move);
        }
    }
}

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

    if (colIndexFromMouseDown != -1)
    {
        // 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;
}

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

private void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
    // If the drag operation was a move then remove and insert the column.
    if (e.Effect == DragDropEffects.Move)
    {
        // The mouse locations are relative to the screen, so they must be 
        // converted to client coordinates.
        Point clientPoint = dataGridView1.PointToClient(new Point(e.X, e.Y));

        // Get the column index of the item the mouse is below. 
        int colIndexOfItemUnderMouseToDrop = dataGridView1.HitTest(clientPoint.X, clientPoint.Y).ColumnIndex;
        if (colIndexOfItemUnderMouseToDrop == -1)
            return;
        colIndexOfItemUnderMouseToDrop = dataGridView1.Columns[colIndexOfItemUnderMouseToDrop].DisplayIndex;
        // Now we have the column's display index.

        if (e.Data.GetDataPresent(typeof(int)))
        {
            int colToMove = (int)e.Data.GetData(typeof(int));
            dataGridView1.Columns[colToMove].DisplayIndex = colIndexOfItemUnderMouseToDrop;
            // Select the column:
            dataGridView1.Columns[colToMove].Selected = true;
        }
    }
}

编辑
新方法:

private DataGridViewColumn columnToMove;

public Form1()
{
    InitializeComponent();

    dataGridView1.Columns.AddRange(new DataGridViewColumn[]
        {
            new DataGridViewTextBoxColumn { Name = "AAA", SortMode = DataGridViewColumnSortMode.NotSortable },
            new DataGridViewTextBoxColumn { Name = "BBB", SortMode = DataGridViewColumnSortMode.NotSortable },
            new DataGridViewTextBoxColumn { Name = "CCC", SortMode = DataGridViewColumnSortMode.NotSortable }
        });
    dataGridView1.Rows.Add(2);
    dataGridView1.AllowUserToOrderColumns = true;
    dataGridView1.MouseDown += dataGridView1_MouseDown;
    dataGridView1.ColumnDisplayIndexChanged += dataGridView1_ColumnDisplayIndexChanged;
}

private void dataGridView1_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e)
{
    if (e.Column == columnToMove)
    {
        dataGridView1.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
        e.Column.Selected = true;
    }
}

private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
    var hti = dataGridView1.HitTest(e.X, e.Y);
    if (hti.Type == DataGridViewHitTestType.ColumnHeader)
    {
        columnToMove = dataGridView1.Columns[hti.ColumnIndex];
        dataGridView1.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
    }
}
于 2014-10-19T10:12:04.773 回答