DataGrid has a DataSource, but thinks it isn't bound

  • Thread starter Thread starter Ruffin Bailey
  • Start date Start date
R

Ruffin Bailey

I'm getting a:
Data cannot be read from a DataGrid which is not bound to a DataTable.
.... exception when I try the following code:

Private Sub testSub(ByVal intCol As Integer, ByVal dgIn As
DataGrid)

Dim dtTemp As DataTable

Try

dtTemp = CType(dgIn.DataSource, DataTable)
Console.WriteLine(dtTemp.Rows(0).Item(0)) ' works, no
problem

' TODO: ERROR HERE
Console.WriteLine(dgIn.BindingContext(dgIn.DataSource, _
dgIn.DataMember).Count)

' This still works (if you comment out the line above)
Console.WriteLine(dtTemp.Rows(0).Item(0))

' But then you get an error here too
Console.WriteLine(dgIn(i, col).ToString)
Catch ex As Exception
mdlErr.errp("mdlGridUtils.autoSizeCol", ex, _
mdlErr.ERR_TYPES.THROW_EXCEPTION)
End Try


End Sub

I thought if "CType(dgIn.DataSource, DataTable)" gave me something,
that means my DataGrid has to have been bound to a DataTable, by
definition. ?? Fwiw, earlier in the code, dgIn.DataSource is set
equal to a DataTable, but I don't think that matters here -- if the
first cast works, this error shouldn't happen, afaict. As I say, when
I write out dtTemp's first row/first col val to the Console that I've
pulled out with the "CType(dgIn.DataSource, DataTable)" bit, I get a
valid value.

intCol = 0 when I'm testing, fwiw.

What am I missing about DataGrids?

Thanks,

Ruffin Bailey
 
I'm getting a:
Data cannot be read from a DataGrid which is not bound to a DataTable.
... exception when I try the following code:
[snip]

Apparently if you don't add the DataGrid to your container control's
Controls collection, the binding methods won't work/aren't hooked up.
This seems like a bug in the DataGrid to me, but I'm sure somebody can
give me the high-level reasoning behind its behaviour.

Here's some simplest-case code. If you have the line
"Me.Controls.Add(dgTemp)" it's all happy. Without that line, the
errors from the first post appear.


Public Class Form1
Inherits System.Windows.Forms.Form


Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

'=======================================
' DEBUG CODE
'=======================================
Dim dsTemp As DataSet
Dim dgTemp As DataGrid = New DataGrid
Dim dtAddy As DataTable


' Below XML file must exist, of course.
dsTemp = Me.readDatasetFromXml("D:\runAddress.xml")
dtAddy = dsTemp.Tables("Addresses")


'*******************************************************
'*******************************************************
' with the following line of code, everything's kosher
' without it, it's not so K
Me.Controls.Add(dgTemp)
'*******************************************************
'*******************************************************


With dgTemp
.DataSource = dtAddy

' Cmds o' bugginess #1
Console.WriteLine(.BindingContext(.DataSource, _
.DataMember).Count)
End With

' Cmds o' bugginess #2
Console.WriteLine(dgTemp(0, 0).ToString)


'=======================================
' END DEBUG CODE
'=======================================

End Sub


Private Function readDatasetFromXml(ByVal strPath As String) _
As DataSet

Dim dsReturn As DataSet = New DataSet

Console.WriteLine(strPath)
dsReturn.ReadXml(strPath)
dsReturn.AcceptChanges()

Return dsReturn
End Function

End Class
 
Ruffin:

I'm sorry but I'm not following the logic of the code at all. Count is a
Property of BindingManagerBase not bindingContext. The usage here just
doesn't seem to make any sense
Ruffin Bailey said:
(e-mail address removed) (Ruffin Bailey) wrote in message
I'm getting a:
Data cannot be read from a DataGrid which is not bound to a DataTable.
... exception when I try the following code:
[snip]

Apparently if you don't add the DataGrid to your container control's
Controls collection, the binding methods won't work/aren't hooked up.
This seems like a bug in the DataGrid to me, but I'm sure somebody can
give me the high-level reasoning behind its behaviour.

Here's some simplest-case code. If you have the line
"Me.Controls.Add(dgTemp)" it's all happy. Without that line, the
errors from the first post appear.


Public Class Form1
Inherits System.Windows.Forms.Form


Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

'=======================================
' DEBUG CODE
'=======================================
Dim dsTemp As DataSet
Dim dgTemp As DataGrid = New DataGrid
Dim dtAddy As DataTable


' Below XML file must exist, of course.
dsTemp = Me.readDatasetFromXml("D:\runAddress.xml")
dtAddy = dsTemp.Tables("Addresses")


'*******************************************************
'*******************************************************
' with the following line of code, everything's kosher
' without it, it's not so K
Me.Controls.Add(dgTemp)
'*******************************************************
'*******************************************************


With dgTemp
.DataSource = dtAddy

' Cmds o' bugginess #1
Console.WriteLine(.BindingContext(.DataSource, _
.DataMember).Count)
End With

' Cmds o' bugginess #2
Console.WriteLine(dgTemp(0, 0).ToString)


'=======================================
' END DEBUG CODE
'=======================================

End Sub


Private Function readDatasetFromXml(ByVal strPath As String) _
As DataSet

Dim dsReturn As DataSet = New DataSet

Console.WriteLine(strPath)
dsReturn.ReadXml(strPath)
dsReturn.AcceptChanges()

Return dsReturn
End Function

End Class
 
William Ryan eMVP said:
I'm sorry but I'm not following the logic of the code at all. Count is a
Property of BindingManagerBase not bindingContext. The usage here just
doesn't seem to make any sense

You might be overlooking that BindingContext implements ICollection:

Public Class BindingContext
Implements ICollection, IEnumerable
(ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfSystemWindowsFormsBindingContextClassTopic.htm)

And ICollection's Count property... "When implemented by a class, gets
the number of elements contained in the ICollection."
(ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfSystemCollectionsICollectionMembersTopic.htm)

The Count property from the ICollection interface doesn't always
"Intellisense up" in VS.NET, but it's still a decent way to access the
data source of a bound control like this DataGrid and ensure it's all
working. I cheese out Count's from all sorts of ICollections when
debugging, and the Count property, to this point, has always been
properly/fully implemented in the .NET objects I've tested.

But even if that line gives you heartburn, hopefully the second method
I was using to figure out if the grid would act bound before I added
it to Form1's Controls collection doesn't:
Console.WriteLine(dgTemp(0, 0).ToString)

The point of both bits of code was that I was hoping to figure out why
a properly instantiated and data bound DataGrid didn't provide access
to its data source in simplest case code, though it often would
provide access in a near exact copy of the code that added its
DataGrid through the Windows.Forms designer. It appears that adding
the DataGrid to the Controls array does the trick -- but there also
seems to be some correlation to the parent form being
visible/completely initialized as well. That is, some
pre-initialization events for the Form don't seem to be good places to
start adding and accessing a data source either (though I don't recall
what I figured out offhand -- just that the above code works, and that
was good enough for me for now).

The CLR should allow you (imo, and I'm sure there's some reference
somewhere saying that this isn't how data binding works) to, say,
create a DataGrid in a generic Class that never puts the DataGrid onto
a Form but still allow you access its DataSource through the binding
context (much less just ask what's in cell 0,0). That there are cases
where you can't (like the one described earlier in the thread) seems
like a bug.

Ruffin Bailey
 
Back
Top