-1

I am creating columns dynamically at runtime. I can delete rows with delete key but I cannot delete columns. Every method I find involves deleting column by column id or column name. In order to do that, I have to find the column name somehow when its selected and then store it somewhere and then write code to delete. My question is why we cannot just delete columns like rows.? Is there any simpler solution to my problem (selecting a column and delete it with key) ? and yes I have gone through almost every post/question before coming here.

Usama Khan
  • 19
  • 6
  • 1
    Because columns are a fixed aspect decided by the developer and rows are variable aspect decided by the user. This is a fairly basic tenet of most tabular data representations, database tables etc. columns model properties, rows model instances – Caius Jard Jan 23 '22 at 12:34
  • *Is there any simpler solution to my problem (selecting a column and delete it with key)* - sure, have the user select the column by clicking the header (I presume you're not allowing them to sort) and then foreach DataGridViewColumn in the DataGrid view's SelectedColumns collection.. remove the column. It's maybe one or two lines of code – Caius Jard Jan 23 '22 at 12:36
  • When i am not allowing to sort. It doesn't select the column. I wrote the code though. Still working it out – Usama Khan Jan 23 '22 at 13:00
  • You set [SelectionMode](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridview.selectionmode?view=windowsdesktop-6.0) to ColumnHeaderSelect, or FullColumnSelect, right? – Caius Jard Jan 23 '22 at 13:14

1 Answers1

0

Well… a possible “crude” yet simple solution is to delete the column if the user clicks on a column header cell. Obviously this is not really a good idea considering most users would expect the grid to sort by that column when the header is clicked and we would still want them to be able to do this. So.. possibly add the requirement that the user must hold the “Ctrl” Key AND click on the column header to delete the column.

However, I would think you need some mechanism to restore (undelete) all the previously removed columns. In that case, we could require the user to press BOTH the “Ctrl” Key and the “Alt” Key to restore all the columns from the original data source. If you are not using a data source then to restore the grid, you may need to re-fill the whole grid manually. Also it should be noted that if the user removes ALL the columns using the “Ctrl” click, then the user will never be able to get the columns back as there will be NO column header cells to click. Possibly always leave at least one column displayed.

You could put this code in the grids ColumnHeaderMouseClick Event and it may look something like…

private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
  if (Control.ModifierKeys.HasFlag(Keys.Control) && Control.ModifierKeys.HasFlag(Keys.Alt)) {
    dataGridView1.DataSource = null;
    dataGridView1.DataSource = YourGridsDataSource;  // or re-fill the grid if it has no data source
    return;
  }
  if (dataGridView1.ColumnCount == 1) {
    return;
  }
  if (Control.ModifierKeys.HasFlag(Keys.Control)) {
    dataGridView1.Columns.Remove(dataGridView1.Columns[e.ColumnIndex].Name);
  }
}


Edit…

After review, it appears clear that a better approach would be to “hide” the column as opposed to actually “removing” the column. This way, if the grid does not have a data source, then you should be able to “unhide” the column and not be forced to “re-create” it. This approach will work regardless if the grid uses a data source or not.

This requires code changes since the comparison…

if (dataGridView1.ColumnCount == 1) { 

will no longer work as the columns are still there. The code below, simply loops through the grid columns and counts how many columns are not visible. Then we use this count to make sure that at least one column always remains visible.

private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
  if (Control.ModifierKeys.HasFlag(Keys.Control) && Control.ModifierKeys.HasFlag(Keys.Alt)) {
    foreach (DataGridViewColumn column in dataGridView1.Columns) {
      column.Visible = true;
    }
    return;
  }
  int count = 0;
  foreach (DataGridViewColumn column in dataGridView1.Columns) {
    if (!column.Visible) {
      count++;
    }
  }
  if (dataGridView1.ColumnCount - count <= 1) {
    return;
  }
  if (Control.ModifierKeys.HasFlag(Keys.Control)) {
    dataGridView1.Columns[e.ColumnIndex].Visible = false;
  }
}
JohnG
  • 9,259
  • 2
  • 20
  • 29
  • The second solution is the one which works like a charm. I wasn't using datasource but still its make it alot more less complex. – Usama Khan Jan 26 '22 at 11:58