1

Using a Windows Forms application.
I have this class, derived from a DataGridView control:

public class CustomDataGridView : DataGridView
{
    private int maxRowsAllowed = 3;

    public CustomDataGridView()
    {
        this.AutoGenerateColumns = false;
        this.AllowUserToAddRows = false;
        this.AllowUserToDeleteRows = false;
        this.ReadOnly = true;
        this.RowsAdded += CustomDataGridView_RowsAdded;
        this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    }

    public void Start()
    {
        this.Columns.Add("col1", "header1");
        this.Columns.Add("col2", "header2");

        // rows added manually, no DataSource
        this.Rows.Add(maxRowsAllowed);
    }

    private void customDataGridView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
    {
        // At this point, while debugging, I realized that CurrentRow is null,
        // doing impossible to change it to a previous one, this way avoiding an exception.
        if (this.Rows.Count > maxRowsAllowed)
        {
            this.Rows.RemoveAt(maxRowsAllowed);
        }
    }
}

Then, from a container class, inside AddRowAtBeginning method, a new row is inserted at 0 index, moving one index down the others.
When RowsAdded event is raised, and only if actual total rows count is greater than rowsAllowed the last is removed.

public class ContainerForm : Form
{
    private CustomDataGridView dgv;

    public ContainerForm()
    {
        InitializeComponent();

        dgv = new CustomDataGridView();

        dgv.Size = new Size(400, 200);
        dgv.Location = new Point(10, 10);
        this.Controls.Add(dgv);

        dgv.Start();
    }

    // Inserts a row at 0 index
    private void aButton_Click(object sender, EventArgs e)
    {
        var newRow = new DataGridViewRow();
        newRow.DefaultCellStyle.BackColor = Color.LightYellow;

        dgv.Rows.Insert(0, newRow);
    }
}

Everything is OK, until the CurrentRow (with the little arrow on header), due to displacement, is choosen to be removed.

I think, that's the reason an System.ArgumentOutOfRangeException is thrown, when RowsAdded escapes, tryng to return to dgv.Rows.Insert(0, newRow) line.

I could not find any solution yet.

Shin
  • 664
  • 2
  • 13
  • 30
  • while it is easy to bypass the problem, I don't know the root cause of it; One of the fix is moving the code of `customDataGridView_RowsAdded` to the end of `aButton_Click` method, inserting after `dgv.Rows.Insert(0, newRow);`. – kennyzx Nov 25 '14 at 07:49
  • Sure, your suggestion is right, but that way, `ContainerForm` has to know `maxRowsAllowed` value, which is something I'm trying to avoid. – Shin Nov 25 '14 at 09:51

1 Answers1

0

try to change this

if (this.Rows.Count > maxRowsAllowed)
{
    this.Rows.RemoveAt(maxRowsAllowed);
}

to this

if (this.Rows.Count > maxRowsAllowed)
{
    // if the number of rows is 10
    // the index of the last item is 9
    // index 10 is out of range
    this.Rows.RemoveAt(maxRowsAllowed -1);
}
Taksil
  • 1
  • 1
  • No, this is not the cause of the problem. If Row.Count is greater than 10 (maxRowsAllowed), the datagridview must have at least 11 rows, `this.Rows.RemoveAt(10)` won't throw an argumentoutofrangeexception. – kennyzx Nov 25 '14 at 07:42