Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hello Xtreme - my first post: please be kind.

 

My application has a read-only datagridview dgvFound fed from a datatable dtFound. This datagridview is permanently displayed whilst the application is running.

 

dtFound is declared public in a module (and exists whilst the application is running).

 

dtFound is fed from any one of around thirty different "finders" that are grouped in three user controls - these finders run sprocs on MSSQL2005 and clear/refill dtFound.

 

Everything works perfectly with dgvFound refreshing nicely in the main form when one of the finders raises a dtFoundIsReady event...

... until the user clicks the header of dgvFound to sort. After the sort everything goes pear-shaped with a NullReferenceException.

 

Some code:


       ...yada yada yada to prepare cmd

       '// exec the sproc
       conn1.Open()
       Dim oDr As SqlDataReader = cmd.ExecuteReader()

       '// clear any entries in existing datatable dtFound
       dtFound.Rows.Clear()
       dtFound.Columns.Clear()
       dtFound.Clear()

       '// refill dtFound
       Dim i As Integer
       Dim count As Integer = oDr.FieldCount - 1

       '//add columns
       For i = 0 To count
           dtFound.Columns.Add(oDr.GetName(i), oDr.GetFieldType(i))
       Next

       '//add rows
       Do While oDr.Read()
           Dim r As DataRow = dtFound.NewRow
           For i = 0 To count
               r(i) = oDr.Item(i)
           Next [b][color="Red"]
'NullReferenceException on next line if dgvFound has been sorted by user [/color]
           dtFound.Rows.Add(r) [/b]
       Loop

       '// raise an event to let the application know dtFound is filled

and then in the event handler:

       Me.dgvFound.DataSource = dtFound

       '// WORKAROUND to evade NullReferenceException after sort
       Dim i As Integer
       For i = 0 To dgvFound.ColumnCount - 1
           Me.dgvFound.Columns(i).SortMode = DataGridViewColumnSortMode.NotSortable
       Next

 

The users can live without sorting - so for the time being I have simply turned sort off, but I would like to understand what is happening here, and how I might be able to leave sorting on.

 

Chris

Posted

Test: find 2 columns x 30 rows, sort the datagrid, rerun the same 2 x 30 to throw the exception.

dtFound is alive when the exception is thrown:

 

>? oDr.fieldcount

2

>? count

1

>? i

2

>? dtfound.rows.count

2

>? dtfound.columns.count

2

 

Here is a (partial) stack trace:

System.NullReferenceException was unhandled
 Message="La référence d'objet n'est pas définie à une instance d'un objet."
 Source="System.Data"
 StackTrace:
   à System.Data.Index.CompareRecords(Int32 record1, Int32 record2)
   à System.Data.Index.IndexTree.CompareNode(Int32 record1, Int32 record2)
   à System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32 mainTreeNodeID, Int32 position, Boolean append)
   à System.Data.RBTree`1.InsertAt(Int32 position, K item, Boolean append)
   à System.Data.Index.InsertRecord(Int32 record, Boolean fireEvent)
   à System.Data.Index.ApplyChangeAction(Int32 record, Int32 action, Int32 changeRecord)
   à System.Data.DataTable.RecordStateChanged(Int32 record1, DataViewRowState oldState1, DataViewRowState newState1, Int32 record2, DataViewRowState oldState2, DataViewRowState newState2)
   à System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException)
   à System.Data.DataTable.InsertRow(DataRow row, Int32 proposedID, Int32 pos, Boolean fireEvent)
   à System.Data.DataRowCollection.Add(DataRow row)
   à <myapplication>.ucFinderXxxx.butShowSearch_Click(Object sender, EventArgs e) dans D:\Development\Projects\<myapplication>\ucFinderXxxx.vb:ligne 158

Sorry it is in "Microsoft French".

 

Chris

Posted

mmm - didn't know I could do this:

>? r
{System.Data.DataRow}
   HasErrors: False
   Item: In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.
   Item: In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.
   Item: In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.
   Item: In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.
   Item: In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.
   ItemArray: {Length=2}
   RowError: ""
   RowState: Added {4}
   Table: {System.Data.DataTable}
>? oDr
{System.Data.SqlClient.SqlDataReader}
   Depth: 0
   FieldCount: 2
   HasRows: True
   IsClosed: False
   Item: In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.
   RecordsAffected: -1
   VisibleFieldCount: 2

 

Chris

Posted

and one more:

>? dtFound
{System.Data.DataTable}
   CaseSensitive: False
   ChildRelations: {System.Data.DataRelationCollection.DataTableRelationCollection}
   Columns: {System.Data.DataColumnCollection}
   Constraints: {System.Data.ConstraintCollection}
   Container: Nothing
   DataSet: Nothing
   DefaultView: {System.Data.DataView}
   DesignMode: False
   DisplayExpression: ""
   ExtendedProperties: Count = 0
   HasErrors: False
   IsInitialized: True
   Locale: {System.Globalization.CultureInfo}
   MinimumCapacity: 50
   Namespace: ""
   ParentRelations: {System.Data.DataRelationCollection.DataTableRelationCollection}
   Prefix: ""
   PrimaryKey: {Length=0}
   RemotingFormat: Xml {0}
   Rows: {System.Data.DataRowCollection}
   Site: Nothing
   TableName: ""

 

Chris

  • 1 month later...
  • 1 month later...
Posted

Thanks, but no - it's not a threading issue.

It really was related to sorting - and the simple fix was to remove the sort before refilling the datatable:

 

 

 


...yada yada

       '// exec the sproc
       conn1.Open()
       Dim oDr As SqlDataReader = cmd.ExecuteReader()

[color="RoyalBlue"]
       '// remove any dtFound sorting before refilling it
       dtFound.DefaultView.Sort = String.Empty
[/color]

       '// clear any entries in existing datatable dtFound
       dtFound.Rows.Clear()
       dtFound.Columns.Clear()
       dtFound.Clear()

       '// refill dtFound
       Dim i As Integer


yada yada...

 

Chris

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...