Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / WinForm General / February 2007

Tip: Looking for answers? Try searching our database.

DataGrid: IndexOutOfRange Exception

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Marcus Kwok - 05 Feb 2007 15:23 GMT
This is a repost of a question I posted to the codeproject.com forums,
but got no responses:
http://www.codeproject.com/script/comments/forums.asp?msg=1872655&forumid=1650#x
x1872655xx


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::Drawing::Point;
       using System::Windows::Forms::DataGrid;
       using System::Windows::Forms::DataGridCell;

       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);
       }
   }

Signature

Marcus Kwok
Replace 'invalid' with 'net' to reply

Mike - 14 Feb 2007 19:50 GMT
> This is a repost of a question I posted to the codeproject.com forums,
> but got no responses:http://www.codeproject.com/script/comments/forums.asp?msg=1872655&for...
[quoted text clipped - 68 lines]
> 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.dat
abinding/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#6c65a2f
4672ffa6c


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;
   }

}
Marcus Kwok - 15 Feb 2007 20:27 GMT
> 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
[quoted text clipped - 7 lines]
>
> http://groups.google.ca/group/microsoft.public.dotnet.framework.windowsforms.dat
abinding/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#6c65a2f
4672ffa6c

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.

Signature

Marcus Kwok
Replace 'invalid' with 'net' to reply

Marcus Kwok - 20 Feb 2007 22:08 GMT
>> This is a repost of a question I posted to the codeproject.com forums,
>> but got no responses:http://www.codeproject.com/script/comments/forums.asp?msg=1872655&for...
[quoted text clipped - 27 lines]
>>     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
[quoted text clipped - 17 lines]
>
> http://groups.google.ca/group/microsoft.public.dotnet.framework.windowsforms.dat
abinding/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#6c65a2f
4672ffa6c

Signature

Marcus Kwok
Replace 'invalid' with 'net' to reply


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.