PC Review


Reply
Thread Tools Rate Thread

DataGrid: IndexOutOfRange Exception

 
 
Marcus Kwok
Guest
Posts: n/a
 
      5th Feb 2007
This is a repost of a question I posted to the codeproject.com forums,
but got no responses:
http://www.codeproject.com/script/co...50#xx1872655xx

I forgot to mention in the above post that I am using Managed C++
(Visual Studio .NET 2003 SP1) / .NET Framework 1.1.


In my application, I have a DataGrid that is used to display search
results from a query into a Firebird SQL database. The DataGrid is not
directly connected to the DB, but instead I perform my query and store
the results in a std::vector, perform some more work on it, then copy
the final results into an ArrayList that the DataGrid is connected to.

So, when I do a search, it goes like this:


/* Obtain final std::vector with query results */

/* search_results_list is an ArrayList */
search_results_list->Clear();

// copy data into ArrayList
tr = db_conn->BeginTransaction();
typedef vector::const_iterator CIter;
for (CIter it = run_ids.begin(); it != run_ids.end(); ++it) {
/* look up Run ID in DB and store the run in disp */
search_results_list->Add(disp);
}
tr->Commit();

/* reset DataSource to refresh the display */
datagrid_search_results->DataSource = 0;
datagrid_search_results->DataSource = search_results_list;


This works fine the first time, however I am having the following
problem. If I click on a row, then subsequently perform another search
that makes the row disappear, I get an IndexOutOfRange exception:


************** Exception Text **************
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Windows.Forms.DataGrid.Edit(String instantText)
at System.Windows.Forms.DataGrid.Edit()
at System.Windows.Forms.DataGrid.OnEnter(EventArgs e)
at System.Windows.Forms.Control.NotifyEnter()
at System.Windows.Forms.ContainerControl.UpdateFocusedControl()


However, my DataGrid has set the ReadOnly property to true. In my other
DataGrid that is used for a different purpose, I was able to solve it by
setting the CurrentSelectedRow property to 0 before removing the
elements, but this does not work in this situation.

I am not sure if it is related to this, but the only event I am handling
for this DataGrid is the MouseUp event, in order to get it to select the
entire row when a cell is clicked:

// Select the entire row when the user clicks on a cell in the row
System::Void datagrid_MouseUp(System::Object* sender, System::Windows::Forms::MouseEventArgs* e)
{
using System:rawing::Point;
using System::Windows::Forms:ataGrid;
using System::Windows::Forms:ataGridCell;

Point pt = Point(e->X, e->Y);
DataGrid* datagrid = __try_cast(sender);
DataGrid::HitTestInfo* hti = datagrid->HitTest(pt);
if (hti->Type == DataGrid::HitTestType::Cell) {
datagrid->CurrentCell = DataGridCell(hti->Row, hti->Column);
datagrid->Select(hti->Row);
}
}

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
 
 
 
Mike
Guest
Posts: n/a
 
      14th Feb 2007
On Feb 5, 8:23 am, ricec...@gehennom.invalid (Marcus Kwok) wrote:
> This is a repost of a question I posted to the codeproject.com forums,
> but got no responses:http://www.codeproject.com/script/co...sg=1872655&for...
>
> I forgot to mention in the above post that I am using Managed C++
> (Visual Studio .NET 2003 SP1) / .NET Framework 1.1.
>
> In my application, I have a DataGrid that is used to display search
> results from a query into a Firebird SQL database. The DataGrid is not
> directly connected to the DB, but instead I perform my query and store
> the results in a std::vector, perform some more work on it, then copy
> the final results into an ArrayList that the DataGrid is connected to.
>
> So, when I do a search, it goes like this:
>
> /* Obtain final std::vector with query results */
>
> /* search_results_list is an ArrayList */
> search_results_list->Clear();
>
> // copy data into ArrayList
> tr = db_conn->BeginTransaction();
> typedef vector::const_iterator CIter;
> for (CIter it = run_ids.begin(); it != run_ids.end(); ++it) {
> /* look up Run ID in DB and store the run in disp */
> search_results_list->Add(disp);
> }
> tr->Commit();
>
> /* reset DataSource to refresh the display */
> datagrid_search_results->DataSource = 0;
> datagrid_search_results->DataSource = search_results_list;
>
> This works fine the first time, however I am having the following
> problem. If I click on a row, then subsequently perform another search
> that makes the row disappear, I get an IndexOutOfRange exception:
>
> ************** Exception Text **************
> System.IndexOutOfRangeException: Index was outside the bounds of the array.
> at System.Windows.Forms.DataGrid.Edit(String instantText)
> at System.Windows.Forms.DataGrid.Edit()
> at System.Windows.Forms.DataGrid.OnEnter(EventArgs e)
> at System.Windows.Forms.Control.NotifyEnter()
> at System.Windows.Forms.ContainerControl.UpdateFocusedControl()
>
> However, my DataGrid has set the ReadOnly property to true. In my other
> DataGrid that is used for a different purpose, I was able to solve it by
> setting the CurrentSelectedRow property to 0 before removing the
> elements, but this does not work in this situation.
>
> I am not sure if it is related to this, but the only event I am handling
> for this DataGrid is the MouseUp event, in order to get it to select the
> entire row when a cell is clicked:
>
> // Select the entire row when the user clicks on a cell in the row
> System::Void datagrid_MouseUp(System::Object* sender, System::Windows::Forms::MouseEventArgs* e)
> {
> using System:rawing::Point;
> using System::Windows::Forms:ataGrid;
> using System::Windows::Forms:ataGridCell;
>
> Point pt = Point(e->X, e->Y);
> DataGrid* datagrid = __try_cast(sender);
> DataGrid::HitTestInfo* hti = datagrid->HitTest(pt);
> if (hti->Type == DataGrid::HitTestType::Cell) {
> datagrid->CurrentCell = DataGridCell(hti->Row, hti->Column);
> datagrid->Select(hti->Row);
> }
> }
>
> --
> Marcus Kwok
> Replace 'invalid' with 'net' to reply


Hi Marcus,

I recently went through the same thing with the datagrid using C#, I
was trying to bind a collection object to my datagrid and whenever I
removed an item from my collection I got an IndexOutOfRangeException.
I was only able to find 1 article that helped me with this problem,
perhaps it may help you as well, I know the discussion centers around
VB.NET but there is some code from this thread done in C# that may
give you an idea on how to solve your problem.

Mike

http://groups.google.ca/group/microsoft.public.dotnet.framework.windowsforms.databinding/browse_thread/thread/f3fd32e6d4ab4556/6c65a2f4672ffa6c?lnk=st&q=System.IndexOutOfRangeException%3A+Index+was+outside+the+bounds+of+the+array.+at+System.Windows.Forms.DataGrid.Edit(String+instantText)+%2B+Object&rnum=1&hl=en#6c65a2f4672ffa6c

public class Customer : IEditableObject
{


struct CustomerData
{
internal string id ;
internal string firstName ;
internal string lastName ;
}


private CustomersList parent;
private CustomerData custData;
private CustomerData backupData;
private bool inTxn = false;


// Implements IEditableObject
void IEditableObject.BeginEdit()
{
Console.WriteLine("Start BeginEdit");
if (!inTxn)
{
this.backupData = custData;
inTxn = true;
Console.WriteLine("BeginEdit - " +
this.backupData.lastName);
}
Console.WriteLine("End BeginEdit");
}


void IEditableObject.CancelEdit()
{
Console.WriteLine("Start CancelEdit");
if (inTxn)
{
this.custData = backupData;
inTxn = false;
Console.WriteLine("CancelEdit - " +
this.custData.lastName);
}
Console.WriteLine("End CancelEdit");
}


void IEditableObject.EndEdit()
{
Console.WriteLine("Start EndEdit" + this.custData.id +
this.custData.lastName);
if (inTxn)
{
backupData = new CustomerData();
inTxn = false;
Console.WriteLine("Done EndEdit - " + this.custData.id +
this.custData.lastName);
}
Console.WriteLine("End EndEdit");
}


public Customer(string ID) : base()
{
this.custData = new CustomerData();
this.custData.id = ID;
this.custData.firstName = "";
this.custData.lastName = "";
}


public string ID
{
get
{
return this.custData.id;
}
}


public string FirstName
{
get
{
return this.custData.firstName;
}
set
{
this.custData.firstName = value;
}
}


public string LastName
{
get
{
return this.custData.lastName;
}
set
{
this.custData.lastName = value;
}
}


internal CustomersList Parent
{
get
{
return parent;
}
set
{
parent = value ;
}
}


private void OnCustomerChanged()
{
if (!inTxn && Parent != null)
{
Parent.CustomerChanged(this);
}
}



}


public class CustomersList : CollectionBase, IBindingList
{
private ListChangedEventArgs resetEvent = new
ListChangedEventArgs(ListChangedType.Reset, -1);
private ListChangedEventHandler onListChanged;

public void LoadCustomers()
{
IList l = (IList)this;
l.Add(ReadCustomer1());
l.Add(ReadCustomer2());
OnListChanged(resetEvent);
}


public Customer this[int index]
{
get
{
return (Customer)(List[index]);
}
set
{
List[index] = value;
}
}


public int Add (Customer value)
{
return List.Add(value);
}


public Customer AddNew()
{
return (Customer)((IBindingList)this).AddNew();
}


public void Remove (Customer value)
{
List.Remove(value);
}


protected virtual void OnListChanged(ListChangedEventArgs ev)
{
if (onListChanged != null)
{
onListChanged(this, ev);
}
}


protected override void OnClear()
{
foreach (Customer c in List)
{
c.Parent = null;
}
}


protected override void OnClearComplete()
{
OnListChanged(resetEvent);
}


protected override void OnInsertComplete(int index, object value)
{
Customer c = (Customer)value;
c.Parent = this;
OnListChanged(new
ListChangedEventArgs(ListChangedType.ItemAdded,
index));
}


protected override void OnRemoveComplete(int index, object value)
{
Customer c = (Customer)value;
c.Parent = this;
OnListChanged(new
ListChangedEventArgs(ListChangedType.ItemDeleted,
index));
}


protected override void OnSetComplete(int index, object oldValue,
object newValue)
{
if (oldValue != newValue)
{


Customer oldcust = (Customer)oldValue;
Customer newcust = (Customer)newValue;


oldcust.Parent = null;
newcust.Parent = this;


OnListChanged(new
ListChangedEventArgs(ListChangedType.ItemAdded, index));
}
}


// Called by Customer when it changes.
internal void CustomerChanged(Customer cust)
{


int index = List.IndexOf(cust);


OnListChanged(new
ListChangedEventArgs(ListChangedType.ItemChanged,
index));
}


// Implements IBindingList.
bool IBindingList.AllowEdit
{
get { return true ; }
}


bool IBindingList.AllowNew
{
get { return true ; }
}


bool IBindingList.AllowRemove
{
get { return true ; }
}


bool IBindingList.SupportsChangeNotification
{
get { return true ; }
}


bool IBindingList.SupportsSearching
{
get { return false ; }
}


bool IBindingList.SupportsSorting
{
get { return false ; }
}


// Events.
public event ListChangedEventHandler ListChanged
{
add
{
onListChanged += value;
}
remove
{
onListChanged -= value;
}
}


// Methods.
object IBindingList.AddNew()
{
Customer c = new Customer(this.Count.ToString());
List.Add(c);
return c;
}


// Unsupported properties.
bool IBindingList.IsSorted
{
get { throw new NotSupportedException(); }
}


ListSortDirection IBindingList.SortDirection
{
get { throw new NotSupportedException(); }
}


PropertyDescriptor IBindingList.SortProperty
{
get { throw new NotSupportedException(); }
}


// Unsupported Methods.
void IBindingList.AddIndex(PropertyDescriptor property)
{
throw new NotSupportedException();
}


void IBindingList.ApplySort(PropertyDescriptor property,
ListSortDirection direction)
{
throw new NotSupportedException();
}


int IBindingList.Find(PropertyDescriptor property, object key)
{
throw new NotSupportedException();
}


void IBindingList.RemoveIndex(PropertyDescriptor property)
{
throw new NotSupportedException();
}


void IBindingList.RemoveSort()
{
throw new NotSupportedException();
}


// Worker functions to populate the list with data.
private static Customer ReadCustomer1()
{
Customer cust = new Customer("536-45-1245");
cust.FirstName = "Jo";
cust.LastName = "Brown";
return cust;
}


private static Customer ReadCustomer2()
{
Customer cust = new Customer("246-12-5645");
cust.FirstName = "Robert";
cust.LastName = "Brown";
return cust;
}


}

 
Reply With Quote
 
Marcus Kwok
Guest
Posts: n/a
 
      15th Feb 2007
Mike <(E-Mail Removed)> wrote:
> I recently went through the same thing with the datagrid using C#, I
> was trying to bind a collection object to my datagrid and whenever I
> removed an item from my collection I got an IndexOutOfRangeException.
> I was only able to find 1 article that helped me with this problem,
> perhaps it may help you as well, I know the discussion centers around
> VB.NET but there is some code from this thread done in C# that may
> give you an idea on how to solve your problem.
>
> Mike
>
> http://groups.google.ca/group/microsoft.public.dotnet.framework.windowsforms.databinding/browse_thread/thread/f3fd32e6d4ab4556/6c65a2f4672ffa6c?lnk=st&q=System.IndexOutOfRangeException%3A+Index+was+outside+the+bounds+of+the+array.+at+System.Windows.Forms.DataGrid.Edit(String+instantText)+%2B+Object&rnum=1&hl=en#6c65a2f4672ffa6c


Hi Mike,
Thanks for your response. In the meantime I have been put onto a
different task, but I will eventually have to return to this issue. I
have saved your post and will definitely examine it in more detail.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
Marcus Kwok
Guest
Posts: n/a
 
      20th Feb 2007
Mike <(E-Mail Removed)> wrote:
> On Feb 5, 8:23 am, ricec...@gehennom.invalid (Marcus Kwok) wrote:
>> This is a repost of a question I posted to the codeproject.com forums,
>> but got no responses:http://www.codeproject.com/script/co...sg=1872655&for...
>>
>> I forgot to mention in the above post that I am using Managed C++
>> (Visual Studio .NET 2003 SP1) / .NET Framework 1.1.
>>
>> In my application, I have a DataGrid that is used to display search
>> results from a query into a Firebird SQL database. The DataGrid is not
>> directly connected to the DB, but instead I perform my query and store
>> the results in a std::vector, perform some more work on it, then copy
>> the final results into an ArrayList that the DataGrid is connected to.
>>
>> So, when I do a search, it goes like this:
>>
>> /* Obtain final std::vector with query results */
>>
>> /* search_results_list is an ArrayList */
>> search_results_list->Clear();
>>
>> // copy data into ArrayList
>> tr = db_conn->BeginTransaction();
>> typedef vector::const_iterator CIter;
>> for (CIter it = run_ids.begin(); it != run_ids.end(); ++it) {
>> /* look up Run ID in DB and store the run in disp */
>> search_results_list->Add(disp);
>> }
>> tr->Commit();
>>
>> /* reset DataSource to refresh the display */
>> datagrid_search_results->DataSource = 0;
>> datagrid_search_results->DataSource = search_results_list;


Well, I managed to find the solution to my problem. After resetting the
DataSource, I needed to refresh the currency manager by adding the
following two lines:

CurrencyManager* cm = __try_cast<CurrencyManager*>(BindingContext->Item[search_results_list]);
cm->Refresh();

>> This works fine the first time, however I am having the following
>> problem. If I click on a row, then subsequently perform another search
>> that makes the row disappear, I get an IndexOutOfRange exception:
>>
>> ************** Exception Text **************
>> System.IndexOutOfRangeException: Index was outside the bounds of the array.
>> at System.Windows.Forms.DataGrid.Edit(String instantText)
>> at System.Windows.Forms.DataGrid.Edit()
>> at System.Windows.Forms.DataGrid.OnEnter(EventArgs e)
>> at System.Windows.Forms.Control.NotifyEnter()
>> at System.Windows.Forms.ContainerControl.UpdateFocusedControl()

>
> I recently went through the same thing with the datagrid using C#, I
> was trying to bind a collection object to my datagrid and whenever I
> removed an item from my collection I got an IndexOutOfRangeException.
> I was only able to find 1 article that helped me with this problem,
> perhaps it may help you as well, I know the discussion centers around
> VB.NET but there is some code from this thread done in C# that may
> give you an idea on how to solve your problem.
>
> http://groups.google.ca/group/microsoft.public.dotnet.framework.windowsforms.databinding/browse_thread/thread/f3fd32e6d4ab4556/6c65a2f4672ffa6c?lnk=st&q=System.IndexOutOfRangeException%3A+Index+was+outside+the+bounds+of+the+array.+at+System.Windows.Forms.DataGrid.Edit(String+instantText)+%2B+Object&rnum=1&hl=en#6c65a2f4672ffa6c


--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
SQLDataReader.GetOrdinal() fails rarely with IndexOutOfRange emanuele.falchero@gmail.com Microsoft ADO .NET 0 11th May 2007 08:52 AM
sporadic IndexOutOfRange error when I databind Jason Shohet Microsoft ADO .NET 1 11th Nov 2005 03:42 PM
Web App, DataSet, IndexOutOfRange Iwan Petrow Microsoft C# .NET 2 3rd May 2005 09:01 AM
Datagrid exception =?Utf-8?B?U2FuamF5?= Microsoft Dot NET Framework Forms 0 9th Mar 2005 04:51 PM
IndexOutOfRange error when calling SHGetSpecialFolderPath Neville Lang Microsoft Dot NET Compact Framework 2 31st Jul 2004 02:40 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 09:03 AM.