DataGrid ArrayList IndexOutOfRangeException

G

Guest

I have a DataGrid bound to an ArrayList. When I delete a 'row' from the
ArrayList the DataGrid throws an 'IndexOutOfRangeException' exception. I
constructed a very simple sample app that reproduces the problem (code
below). This sample simply populates the grid from the array. When you click
the button it deletes the current row. At that point the exception is thrown.
If anyone could suggest what I'm doing wrong I'd appreciate it. TIA

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication1
{
public class Form1 : System.Windows.Forms.Form
{
private ArrayList m_oArrayList=new ArrayList();
private System.Windows.Forms.DataGrid m_oDataGrid;
private System.Windows.Forms.Button button1;

private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();

m_oArrayList.Add(new NameValuePair("NameOne","ValueOne"));
m_oArrayList.Add(new NameValuePair("NameTwo","ValueTwo"));
m_oArrayList.Add(new NameValuePair("NameThree","ValueThree"));
m_oArrayList.Add(new NameValuePair("NameFour","ValueFour"));
m_oArrayList.Add(new NameValuePair("NameFive","ValueFive"));
m_oArrayList.Add(new NameValuePair("NameSix","ValueSix"));
m_oArrayList.Add(new NameValuePair("NameSeven","ValueSeven"));

m_oDataGrid.SetDataBinding(m_oArrayList,"");
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

private void InitializeComponent()
{
this.m_oDataGrid = new System.Windows.Forms.DataGrid();
this.button1 = new System.Windows.Forms.Button();

((System.ComponentModel.ISupportInitialize)(this.m_oDataGrid)).BeginInit();
this.SuspendLayout();
this.m_oDataGrid.DataMember = "";
this.m_oDataGrid.HeaderForeColor =
System.Drawing.SystemColors.ControlText;
this.m_oDataGrid.Location = new System.Drawing.Point(16, 40);
this.m_oDataGrid.Name = "m_oDataGrid";
this.m_oDataGrid.Size = new System.Drawing.Size(264, 176);
this.m_oDataGrid.TabIndex = 0;
this.button1.Location = new System.Drawing.Point(80, 8);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(64, 24);
this.button1.TabIndex = 1;
this.button1.Text = "delete";
this.button1.Click += new System.EventHandler(this.button1_Click);
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 229);
this.Controls.Add(this.button1);
this.Controls.Add(this.m_oDataGrid);
this.Name = "Form1";
this.Text = "Form1";

((System.ComponentModel.ISupportInitialize)(this.m_oDataGrid)).EndInit();
this.ResumeLayout(false);
}

[STAThread] static void Main()
{
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e)
{
m_oArrayList.RemoveAt(m_oDataGrid.CurrentRowIndex);
m_oDataGrid.Refresh();
}
}

public class NameValuePair
{
private string m_strName=string.Empty;
public string Name{get{return m_strName;} set{m_strName=value;}}

private string m_strValue=string.Empty;
public string Value{get{return m_strValue;} set{m_strValue=value;}}

public NameValuePair(string strName,string strValue)
{
m_strName = strName;
m_strValue =strValue;
}
}
}
 
P

pop.nagarro.com

The problem is in your datagrid. When you delete the item from the
arraylist, your datagrid still has visiblerows as 7 and tries to find a
name/value pair from arraylist where it accesses the 6th index, which is not
there now.

The solution:
private void button1_Click(object sender, System.EventArgs e)

{

m_oArrayList.RemoveAt(m_oDataGrid.CurrentRowIndex);

m_oDataGrid.DataSource = null;

m_oDataGrid.SetDataBinding(m_oArrayList, "");

}

hope that solves your problem.

Vivek


km said:
I have a DataGrid bound to an ArrayList. When I delete a 'row' from the
ArrayList the DataGrid throws an 'IndexOutOfRangeException' exception. I
constructed a very simple sample app that reproduces the problem (code
below). This sample simply populates the grid from the array. When you
click
the button it deletes the current row. At that point the exception is
thrown.
If anyone could suggest what I'm doing wrong I'd appreciate it. TIA

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication1
{
public class Form1 : System.Windows.Forms.Form
{
private ArrayList m_oArrayList=new ArrayList();
private System.Windows.Forms.DataGrid m_oDataGrid;
private System.Windows.Forms.Button button1;

private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();

m_oArrayList.Add(new NameValuePair("NameOne","ValueOne"));
m_oArrayList.Add(new NameValuePair("NameTwo","ValueTwo"));
m_oArrayList.Add(new NameValuePair("NameThree","ValueThree"));
m_oArrayList.Add(new NameValuePair("NameFour","ValueFour"));
m_oArrayList.Add(new NameValuePair("NameFive","ValueFive"));
m_oArrayList.Add(new NameValuePair("NameSix","ValueSix"));
m_oArrayList.Add(new NameValuePair("NameSeven","ValueSeven"));

m_oDataGrid.SetDataBinding(m_oArrayList,"");
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

private void InitializeComponent()
{
this.m_oDataGrid = new System.Windows.Forms.DataGrid();
this.button1 = new System.Windows.Forms.Button();

((System.ComponentModel.ISupportInitialize)(this.m_oDataGrid)).BeginInit();
this.SuspendLayout();
this.m_oDataGrid.DataMember = "";
this.m_oDataGrid.HeaderForeColor =
System.Drawing.SystemColors.ControlText;
this.m_oDataGrid.Location = new System.Drawing.Point(16, 40);
this.m_oDataGrid.Name = "m_oDataGrid";
this.m_oDataGrid.Size = new System.Drawing.Size(264, 176);
this.m_oDataGrid.TabIndex = 0;
this.button1.Location = new System.Drawing.Point(80, 8);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(64, 24);
this.button1.TabIndex = 1;
this.button1.Text = "delete";
this.button1.Click += new System.EventHandler(this.button1_Click);
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 229);
this.Controls.Add(this.button1);
this.Controls.Add(this.m_oDataGrid);
this.Name = "Form1";
this.Text = "Form1";

((System.ComponentModel.ISupportInitialize)(this.m_oDataGrid)).EndInit();
this.ResumeLayout(false);
}

[STAThread] static void Main()
{
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e)
{
m_oArrayList.RemoveAt(m_oDataGrid.CurrentRowIndex);
m_oDataGrid.Refresh();
}
}

public class NameValuePair
{
private string m_strName=string.Empty;
public string Name{get{return m_strName;} set{m_strName=value;}}

private string m_strValue=string.Empty;
public string Value{get{return m_strValue;} set{m_strValue=value;}}

public NameValuePair(string strName,string strValue)
{
m_strName = strName;
m_strValue =strValue;
}
}
}
 
G

Guest

Reassigning the DataSource in this way is a hack and doesn't seem to work in
all cases. But I have found the following to be reliable.

private void button1_Click(object sender, System.EventArgs e)
{
m_oArrayList.RemoveAt(m_oDataGrid.CurrentRowIndex);

CurrencyManager cm;
cm = (CurrencyManager)m_oDataGrid.BindingContex[m_oDataGrid.DataSource];
cm.Refresh();
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top