Home > Blockchain >  Why dataGridView.Rows.Clear() doesn't work?
Why dataGridView.Rows.Clear() doesn't work?

Time:06-10

I have a WinForms application with a DataGridView set with default settings to allow users to add rows. But I want to remove rows programmatically as well.

When I run the function dataGridView.Rows.Clear() nothing happens - the rows remain in the DataGridView.

I got as far as changing the edit mode, removing the data source, and refreshing:

dataGridView.EditMode = DataGridViewEditMode.EditProgrammatically;
dataGridView.DataSource = null;
dataGridView.Rows.Clear();
dataGridView.Refresh();
dataGridView.EditMode = DataGridViewEditMode.EditOnKeystroke;

But still, the rows added by the user are visible in the DGV. How can I remove these rows?,

EDIT: Screenshot of the DGV:

DGV

CodePudding user response:

Did you try iterating through dataGridViewError.Rows collection and remove one by one?

 foreach (DataGridViewRow row in dataGridViewError.Rows)   
 {
  try
  {
    dataGridViewError.Rows.Remove(row);
  }
  catch (Exception) { } 
}

CodePudding user response:

Your question is Why dataGridView.Rows.Clear() doesn't work and the answer is that your posted code is acting on the DataSource property but that property doesn't appear to be set up (or utilized) correctly.

First you need a class that will act as a Model for a Row (in other words it declares the columns you want to have in your DataGridView). Making properties {get;set;} means the user will be able to edit those properties in the DataGridView.

public class Record
{
    public string Licznic { get; set; }
    public string Procent { get; set; }
}

What makes DataGridView easy to use is that it's designed to configure itself automatically based on this class. Just make a BindingList<Record> and attach it to the DataSource property by overriding OnHandleCreated in your Main Form class:

BindingList<Record> DataSource = new BindingList<Record>();
protected override void OnHandleCreated(EventArgs e)
{
    base.OnHandleCreated(e);

    // Attach the DataSource to your DataGridView
    // Now changes to source records refresh in the view.
    dataGridView1.DataSource = this.DataSource;

    // Adding one or more records will generate the columns.
    DataSource.Add(new Record { Licznic = "ABC123", Procent = "XYZ" });
    DataSource.Add(new Record { Licznic = "DEF456", Procent = "PQR" });

    // Use string indexer to get a column
    dataGridView1.Columns[nameof(Record.Licznic)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    dataGridView1.Columns[nameof(Record.Licznic)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}

If you run this code, you get this:

generated columns

When the clear button on the UI is clicked, it now acts on the DataSource not the UI and you will find this very effective:

private void buttonClear_Click(object sender, EventArgs e)
{
    DataSource.Clear();
}

EDIT

Based on your comment that the data grid view is loaded empty, make this minor change in OnHandleCreated to achieve that initial state:

// Adding one or more records will generate the columns.
DataSource.Add(new Record { Licznic = "", Procent = "" });

// Based on your comment that the DataGridView is "Loaded Empty"
// you would want to clear this record immediately after the
// automatic configuration has taken place.
DataSource.Clear();
  • Related