Deleting ArrayList element from DataGrid

N

nadeem_far

Hello All,

I have been trying to solve the following issue and it seems like there
is no solution available any where and maybe people at Microsoft should
may be of some help.

I am writing a .Net desktop application using C# and framework version
1.1

I have a arraylist of some objects of the same type and I am showing
them in a datagrid using

Daragrid1. DataSource = objArray;

When I try to delete any of the rows from the datagrid I get the
following error message.

An unhandled exception of type 'System.IndexOutOfRangeException'
occurred in system.windows.forms.dll

Additional information: No value at index 1

Here is a code snippet

public class Customer
{

private string _customerName;

public Customer (string name)
{
_customerName = name;
}
public string CustomerName
{
get { return _customerName ;}
set { _customerName = value;}
}
}

public class Customerlist
{

public ArrayList customerList;

Customerlist()
{
customerList = new ArrayList();
customerList.Add(new Customer ("John"));
customerList.Add(new Customer ("Doe"));
customerList.Add(new Customer ("Dave"));
}

public void Remove (int i )
{
customerList.RemoveAt(i);
}
}

In my form I create a variable of Customerlist and bind it to the grid
as
dg1.DataSource = Customerlist.customerList;

I have a button, when I select a row in the grid and hit Delete I do
the following

dg1.DataSource = null;
customerList.Remove ( dg1.currentRowIndex);
dg1.DataSource = Customerlist.customerList;

After this code is called I get the above error. Has anyone solved this
problem. I will be thankful if some one can give me the solution.

Thanks

nad
 
P

Pete Davis

The problem is that the grid doesn't get updates from an ArrayList after
it's first bound. So when you bind the grid to an arraylist with say, 100
items, it always thinks that array list has 100 items.

You should create your own collection class derived from IBindingList and
then implement the ListChanged event. You can store everything underneath in
an array list and simply call through to the array list for all the method
implementations.

It's pretty simple to do and this will give you the kind of functionality
you're looking for.

Optionally, you can try doing the following, after modifying the ArrayList's
contents:

(BindingContext[grid.DataSource] as CurrencyManager).Refresh();

But this is really sort of a hack. Implementing IBindingList is definitely
the preferable solution.

Pete
 
N

nadeem_far

Hi Pete,

Thanks for the help but I will need some more help in using
IBindingList.
I will prefer this way but I could not get much help from MSDN
regarding the implementation of IBindlingList.

some more help regarding such implementation will be nice.

Thanks


Nad
 
P

Pete Davis

Simply create your class::

public class MyCollection : IBindingList
{
private ArrayList _list = new ArrayList();
.....
}

You don't really need to do much for the implementation of the methods.
Simply add support for whatever functionality you want.

You'll probably want to implement an OnListChanged() method along these
lines:

protected void OnListChanged(ListChangedEventArgs args)
{
if (null != ListChanged)
{
ListChanged(this, args);
}
}


Since IBindingList inherits IList, ICollection, and IEnumerable, you'll have
to implement all of these as well. Simply ass them through to the underlying
ArrayList, such as:

public object this[int index]
{
get
{
return _list[index];
}
set
{
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged,
index, -1));
_list[index] = value;
}
}

public void RemoveAt(int index)
{
_list.RemoveAt(index);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, -1,
index));
}

public void Insert(int index, object value)
{
_list.Insert(index, value);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded,
index, -1));
}

public void Remove(object value)
{
int index = _list.IndexOf(value);
_list.Remove(value);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, -1,
index));
}

and so on and so forth. Simply call OnListChanged with the appropriate
arguments for operations that change the collection.

Pete
 
N

nadeem_far

Hi Pete,

Thank you so much for the tips. I have implemented the IBindingList
Interface successfully.
Actuallly I was not able to understand how my Class will notify the
CurrencyManager of DataGrid.

Thanks alot..

Nad
 
P

Pete Davis

When you bind a class to the grid that implement IBindingList, the
CurrencyManager subscribes to the ListChanged event in the IBindingList. By
handling the ListChanged events, it can tell when items are added, removed,
etc, and then it can update its data to reflect those changes, allowing the
grid to stay in sync with the underlying data.
 

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