Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > DataGridView thinks it has more rows than it has - and exceptions are not catched
 

DataGridView thinks it has more rows than it has - and exceptions are not catched

I have a program for editing a database. The program has, amongt others, a DataGridView with rows from the database, and a TreeView that applies a filter to the DataGridView. It also has a separate DataGridView that only displays added, modified and deleted items.

Because there are thousands of rows in the database, and they belong to different categories (maintained by the TreeView), a user can double click a field in one of the DataGridViews to find the row. When that happens, the program searches for a corresponding node in the TreeView, and if it finds it, the node is selected:

        // Search for component when user double clicks it

        private void dgvFindComponent(object sender, DataGridViewCellEventArgs e)

        {

            try

            {

                searching = true; // Row validation would cause problems while doing a search

                if (e.ColumnIndex >= 0 && e.RowIndex >= 0) // Ignore headers

                {

                    // Find category

                    DataGridViewRow findRow = ((DataGridView)sender).CurrentRow;

                    DataRowView findRowView = ((DataRowView)findRow.DataBoundItem);

                    int cellIndex = ((DataGridView)sender).CurrentCellAddress.X;



                    TreeNode[] findNodes = trvCategories.Nodes.Find(findRow.Cells["Part Type"].Value.ToString() + "\\", true);

                    if (findNodes.Length != 0)

                    {

                        trvCategories.SelectedNode = findNodes[0];

                    }



                    // Clear filter

                    btnClearFilter_Click(null, null);



                    // Find component

                    foreach (DataGridViewRow row in dgvEditor.Rows)

                    {

                        if (row.DataBoundItem != null && ((DataRowView)row.DataBoundItem).Row == findRowView.Row)

                        {

                            dgvEditor.Focus();

                            dgvEditor.CurrentCell = row.Cells[cellIndex];

                            break;

                        }

                    }

                }

                searching = false;

            }

            catch (Exception ex) { debugOutput(ex); }

        }

This part works fine. As you can see, I use a "searching" variable to stop row validation, which would make the problem to appear less often - but still in some situations.

What happens is that when a node is found and selected, a rowFilter is applied to the DataGridView, and this (I presume) triggers a RowValidating event. In this event, the rowIndex that is sent via the DataGridViewCellCancelEventArgs is larger than the number of rows currently in the DataGridView - altough Rows.Count returns a large enough value. Because of this, an IndexOutOfRangeException is thrown. The RowValidating code is:

        private void dgvEditor_RowValidating(object sender, DataGridViewCellCancelEventArgs e)

        {

            try

            {

                //if (!searching)

                {

                    DataGridViewRow row = ((DataGridView)sender).Rows[e.RowIndex];



                    // Auto-fill some fields. Only on new (uncomitted) items.

                    if (row.DataBoundItem != null && ((DataRowView)row.DataBoundItem).Row.RowState == DataRowState.Detached || ((DataRowView)row.DataBoundItem).Row.RowState == DataRowState.Added)

                    {

                        // Set Part Type for new components from TreeView

                        if (row.Cells["Part Type"].Value.ToString() == String.Empty)

                        {

                            row.Cells["Part Type"].Value = getCurrentCategory();

                        }



                        // If no Created Date is set, use todays date

                        if (row.Cells["Created Date"].Value.ToString() == string.Empty)

                        {

                            row.Cells["Created Date"].Value = DateTime.Now.ToString("yyyy-MM-dd");

                        }



                        // If no revision is set, use a default

                        if (row.Cells["Revision"].Value.ToString() == string.Empty)

                        {

                            row.Cells["Revision"].Value = "p1_r1.0";

                        }



                        // If no initials are set, use value from textbox.

                        if (row.Cells["Created By"].Value.ToString() == string.Empty)

                        {

                            row.Cells["Created By"].Value = txtInitials.Text.ToUpper();

                        }

                    }



                    // Error on empty compulsory fields

                    dgvSetErrors(row);

                }

            }

            catch (Exception ex) { debugOutput(ex); }

        }<br/>


I have commented out the if (!searching) to make the problem appear more often.

My problems are:
1: I can't find a way to check if the row is valid. The problem appears when checking row.DataBoundItem.
2: Even though i have a try ... catch around the whole code, I get standard error messages stating that I should catch the exception myself.

edit: Problem 2 was solved by creating a dummyhandler for the DataError event... Doesn't DataGridView follow the standard way of handling exceptions?
s__  Monday, July 20, 2009 10:03 AM
Hi,

Could you please reproduce the problem in a simple project? If so, please send the project to me for research. My email box is v-lliu@microsoft.com.

Thanks,
Linda Liu
Please remember to mark the replies as answers if they help and unmark them if they provide no help. end us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Linda Liu  Wednesday, July 29, 2009 3:09 AM

You can use google to search for other answers

Custom Search

More Threads

• Adding code to a visual basic 2005 button to run a sql query
• VS 2005 - Easiest way to get two related tables in one datagridview?
• To know the DataSet contains data or not in VB .net
• Data Binding and DataSet.GetChanges()
• displying values in datagrid view
• Image and Text in ImageColumn in DataGridView
• Datagridview Combo Box
• Need Help with Variables and Databinding
• Prevent insert in a datagrid
• Datagrid onchange event