Problem hiding current column in DataGridView – exception “Current cell cannot be set to an invisibl

Environment VS2008. UserControl (in a panel in a form) with a DataGridView and a ListView (and several others).

I have implemented drag-drop between the DataGridView and the ListView: I can drag a DataGridView cell to the ListView thereby displaying the column name in the ListView and hiding the column in the DataGridView – to the end user: drag a column out of (remove
from) the DataGridView. Likewise I can drag a column name from the ListView and drop it on the DataGridView and the column becomes visible again in the DataGridView. The latter operation performs nicely. Dragging a column out of the DataGridView is implemented
this way:

1. dgv_CellMouseDown event: save current columnindex as column to hide in int dgvdragcolno and initiate drag-drop: dgv.DoDragDrop(dgvdragcolno, DragDropEffects.Copy);

(first I tried to use dgv MouseDown event, but this blocks column resizing and sorting)

2. dgv DragEnter event does: e.Effect = DragDropEffects.Copy;

3. in ListView DragDrop event I add the dgv column name to the ListView, set the dgv CurrentCell to the nearest visible cell (in the same row) away from the cell where drag is initiated, and finally: dgv.Columns[dgvdragcolno].Visible = false; – thereby hiding
the column where drag started.

Problem: Exception: “Current cell cannot be set to an invisible cell” in runtime (where I can select Details, Continue, Exit). 

It looks like the dgv CurrentCell is reset to the original cell (where drag started) and because this column is now invisible, gives the above exception.

I have tried to move the column hiding code several places (like dgv CurrentCellChanged event handler) without success. The ideal place I think would have been in the ListView MouseUp event, but this event never fires. (ListView MouseDown event fires ok,
but I have not been able to get ListView MouseUp event to fire. I have tried replacing the ListView with a ListBox with the same result as for ListView. For ListBox the MouseUp fires, but ONLY if ListBox MouseDown event fires first which is of no help when
dragging from DataGridView to ListBox when ListBox MouseUp event never fires)

Can anybody help? 


Hi kegerdal,Is the datagridView dataBinded? Would you show us your code here(without sensitive information), so it will be easire for us to help.Have you tried setting the CurrentCell to another cell after

It does not matter whether CurrentCell is set before or after  hiding column.I have stripped down the code to the following test application that demonstrates the problem (have removed the databinding of the DataGridView and reduced no. of columns to just a few.This application shows the DataGridView and the ListView with a ListBox where I am logging the events that fires.Some strange things: When clicking the mouse inside the ListView the MouseDown fires (as expected) and then the MouseUp event fires immediately (before releasing the mouse button)! This must be wrong!When I click the mouse in the DataGridView and hold the key down and releases it over the ListView it is the DataGridView MouseUp event that fires – I whould have expected the ListView MouseUp event?To see the exception problem: (left) click a cell in the DataGridView and drag it to the ListView (and then release the mouse button). The code: Program.cs:using System;using System.Collections.Generic;using System.Linq;using System.Windows.Forms; namespace testdragdrop{ static class Program { ///

 /// The main entry point for the application. ///

 [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } }}———————————————————————-Form1.cs:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms; namespace testdragdrop{ public partial class Form1 : Form { int dgvdragcolno = -1, lvdragcolno = -1;  public Form1() { InitializeComponent(); }  void Log(string txt) { int ix = lxLog.Items.Add(txt); lxLog.SelectedIndex = ix;// Let focus follow last line in listbox lxLog.SelectedIndex = -1; Application.DoEvents(); }  private void Form1_Load(object sender, EventArgs e) {} private void dgvWork_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e){Log(“dgvWork_CellMouseDown”);lvdragcolno = -1;if (e.Button == MouseButtons.Left){int colix = e.ColumnIndex;int rowix = e.RowIndex;if (rowix >= 0){DataGridView dgv = (DataGridView)sender;dgvdragcolno = colix;dgv.DoDragDrop(dgvdragcolno, DragDropEffects.Copy);}}} private void dgvWork_DragEnter(object sender, DragEventArgs e){Log(“dgvWork_DragEnter”);e.Effect = DragDropEffects.Copy;} private void dgvWork_DragDrop(object sender, DragEventArgs e){Log(“dgvWork_DragDrop”);if (e.Data.GetDataPresent(typeof(int))){DataGridView dgv = (DataGridView)sender;if ((lvdragcolno >= 0) && (lvdragcolno < dgv.Columns.Count)){for (int ix = 0; ix < lvColumns.Items.Count; ix++){ListViewItem lvi = lvColumns.Items[ix];int itmp = 0;if (int.TryParse(lvi.SubItems[1].Text, out itmp) && (itmp == lvdragcolno)){lvi.Remove();break;}}if (!dgv.Columns[lvdragcolno].Visible)dgv.Columns[lvdragcolno].Visible = true;//// Set current cell to cell in newly visible column//int rowix = dgv.CurrentCell.RowIndex;//dgvWork.CurrentCell = dgv[lvdragcolno, rowix];}}} private void dgvWork_DragLeave(object sender, EventArgs e){Log("dgvWork_DragLeave");} private void dgvWork_MouseDown(object sender, MouseEventArgs e){Log("dgvWork_MouseDown");} private void dgvWork_MouseUp(object sender, MouseEventArgs e){Log("dgvWork_MouseUp");dgvdragcolno = -1;} private void lvColumns_MouseDown(object sender, MouseEventArgs e){Log("lvColumns_MouseDown");dgvdragcolno = -1;if (e.Button == MouseButtons.Left){ListView lv = (ListView)sender;ListViewHitTestInfo info = lv.HitTest(e.X, e.Y);if (info.Item != null){int.TryParse(info.Item.SubItems[1].Text, out lvdragcolno);lv.DoDragDrop(lvdragcolno, DragDropEffects.Copy);}elselvdragcolno = -1;}elselvdragcolno = -1;} private void lvColumns_DragEnter(object sender, DragEventArgs e){Log("lvColumns_DragEnter");e.Effect = DragDropEffects.Copy;} private void lvColumns_DragLeave(object sender, EventArgs e){Log("lvColumns_DragLeave");} private void lvColumns_DragDrop(object sender, DragEventArgs e){Log("lvColumns_DragDrop");if (e.Data.GetDataPresent(typeof(int))){int idata = (int)e.Data.GetData(typeof(int));if (dgvdragcolno >= 0){bool found = false;int rowix = dgvWork.CurrentCell.RowIndex;string colname = dgvWork.Columns[dgvdragcolno].HeaderText; for (int ix = 0; ix < lvColumns.Items.Count; ix++){if (lvColumns.Items[ix].SubItems[0].Text.Equals(colname)){found = true;// Already present in listviewbreak;}}if (!found){// Check whether more than one visible columnint viscount = 0;for (int ix = 0; (ix < dgvWork.Columns.Count) && (viscount < 2); ix++)if (dgvWork.Columns[ix].Visible)viscount++;if (viscount < 2){MessageBox.Show("At least one column must be left visible!", "Columns", MessageBoxButtons.OK);return;}ListViewItem lvi = new ListViewItem(colname);lvi.SubItems.Add(dgvdragcolno.ToString());lvColumns.Items.Add(lvi);} // Find nearest visible cell and set it as current cellint cx = dgvdragcolno - 1;while ((cx >= 0) && !dgvWork.Columns[cx].Visible)cx–;if (cx < 0){cx = dgvdragcolno + 1;while ((cx < dgvWork.Columns.Count) && !dgvWork.Columns[cx].Visible)cx++;}dgvWork.CurrentCell = dgvWork[cx, rowix];dgvWork.Columns[dgvdragcolno].Visible = false;

Hi  kegerdal,Sorry for the late reply, the “Alert me” on MSN is not working these days. I will reproduce as the code you provide and give you update as soon as possible.Sincerely,