I have a WinForm with DataGridView
, my goal is to drag one column and drop it on other column index. I know column reordering is possible by using AllowUserToOrderColumns = true
. But I have to perform other operations on DGV. That's why I need the target column index at a mouse-up event. To do that, I use HitTestInfo
:
System.Windows.Forms.DataGrid.HitTestInfo myHitTest;
myHitTest = dataGrid1.HitTest(e.X, e.Y);
int p = myHitTest.ColumnIndex;
When I click on the first DGV column, this code runs and gives me the column's index (p
). The problem is when I drop it on the other column of DGV, I'd like to know the target column's index, with the same code p = -1
, I think because the HitTestInfo
member returns a value on a MouseDown
and not on a MouseUp
. If anyone can tell me how to do it, it would be very great.
You can create two HitTestInfo objects, one in the MouseDown
and one in the MouseUp
.
IMO, you also should use the DataGridView.HitTestInfo
class, not DataGrid.HitTestInfo
and try to not call or name DataGridViews
DataGrids
, which is a similar but different Control from 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);
}
Update: To find the visible index of a column after the columns have been reordered simply use:
dataGrid1.Columns[myHitTestUp.ColumnIndex].DisplayIndex;
Before I found that, I wrote this little helper function, which does the same:
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;
}
To find out which Column was shuffled seems to be a bit harder. There is an event, which gets called for each column that was affected and it always gets called first for the one that was dragged along. Here is one way to do it:
Create to variables at class level:
List<DataGridViewColumn> shuffled = new List<DataGridViewColumn>();
DataGridViewColumn shuffledColumn = null;
Remember the first column:
private void dgvLoadTable_ColumnDisplayIndexChanged(
object sender, DataGridViewColumnEventArgs e)
{
if (shuffledColumn == null) shuffledColumn = e.Column;
}
Forget what happend before:
private void dgvLoadTable_MouseDown(object sender, MouseEventArgs e)
{
shuffledColumn = null;
}
Now you can use it. Selecting Columns is, however, not going well with shuffling them! If you do
shuffledColumn.Selected = true;
it will only be selected if the SelectionMode
is either FullColumnSelect
or ColumnHeaderSelect
- In either mode the shuffling will not work, I'm afraid..