1

I am trying to update the row increment number in a DataGridView in my WinForms application after deleting a row or rows. I have looked at sources and the all point on how to add the incrementing to a column in DataTable. My DataGridView is bound to my DataTable, and that is bound to a DataSet.

How I created by datatable:

DataColumn itemNumber = new DataColumn();
itemNumber.ColumnName = "ItemNumber";
itemNumber.AutoIncrement = true;
itemNumber.AutoIncrementSeed = 1;
itemNumber.AutoIncrementStep = 1;

DataColumn article = new DataColumn();
article.ColumnName = "Article";
article.ReadOnly = true;

DataColumn description = new DataColumn();
description.ColumnName = "Description";
description.ReadOnly = true;

DataColumn type = new DataColumn();
type.ColumnName = "Type";
type.ReadOnly = true;

//add to datatable
dt.Columns.Add(itemNumber);
dt.Columns.Add(article);
dt.Columns.Add(description);
dt.Columns.Add(type);

Removing a row from the DataGridView

foreach (DataGridViewRow row in dgvView.SelectedRows)
{
    dgvView.Rows.RemoveAt(row.Index);
}

If I have 5 rows, and delete one. I would like the increment values to start from the 1,2,3,4 etc...

Can someone point me on how to achieve this?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Harry
  • 3,031
  • 7
  • 42
  • 67

1 Answers1

0

I can't think of an efficient way to do this, but here are some ideas that may work with small data sets.

Keep up with the values yourself

1) Don't define the column as an AutoIncrement column):

DataColumn itemNumber = new DataColumn();
itemNumber.ColumnName = "ItemNumber";
//itemNumber.AutoIncrement = true;
//itemNumber.AutoIncrementSeed = 1;
//itemNumber.AutoIncrementStep = 1;

2) Handle the DataGridView.RowsAdded and DataGridView.RowsRemoved events and "reset" the values:

private void dgvView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
    if (dgvView.Columns.Contains("ItemNumber"))
    {
        foreach (DataGridViewRow r in dgvView.Rows)
        {
            r.Cells["ItemNumber"].Value = r.Index + 1;
        }
    }
}

private void dgvView_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
    if (dgvView.Columns.Contains("ItemNumber"))
    {
        foreach (DataGridViewRow r in dgvView.Rows)
        {
            r.Cells["ItemNumber"].Value = r.Index + 1;
        }
    }
}

Regenerate the values by rebuilding the DataTable and rebinding to it

1) Define the helper method below:

private DataTable ResetAutoIncrementColumn(DataTable dt, string autoIncrementColumnName)
{
    DataTable result = new DataTable();
    DataColumn itemNumber = new DataColumn(autoIncrementColumnName);
    itemNumber.AutoIncrement = true;
    itemNumber.AutoIncrementSeed = 1;
    itemNumber.AutoIncrementStep = 1;
    result.Columns.Add(itemNumber);

    dt.Columns.Remove(autoIncrementColumnName);
    result.Merge(dt, true);
    return result;
}

2) Call it at the appropriate time (e.g. after a series of deletes as in the original question):

dt = ResetAutoIncrementColumn(dt, "ItemNumber");
dt.Columns["ItemNumber"].SetOrdinal(0);
dgvView.DataSource = dt;
dgvView.Columns["ItemNumber"].DisplayIndex = 0;

If you are just looking for a visual row number

Also, if you are just looking to have a visual row number on the DataGridView (and you don't care about the value being present in the underlying DataTable), you can handle the DataGridView.RowPostPaint event as follows (pulled from https://stackoverflow.com/a/12840794/3085273):

private void dgGrid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    var grid = sender as DataGridView;
    var rowIdx = (e.RowIndex + 1).ToString();

    var centerFormat = new StringFormat() 
    { 
        // right alignment might actually make more sense for numbers
        Alignment = StringAlignment.Center, 
        LineAlignment = StringAlignment.Center
    };

    var headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height);
    e.Graphics.DrawString(rowIdx, this.Font, SystemBrushes.ControlText, headerBounds, centerFormat);
}
Community
  • 1
  • 1
gannaway
  • 1,872
  • 12
  • 14
  • thanks, I can see this is not an efficient. Seems like a lot of work just to set reset the increment values. But I think you are correct, for this work the incrementing should be handled by adding each row.Index +1. I will add the rowsAdded and rowsRemoved handler to this. – Harry Dec 28 '14 at 00:12