none
'Unable to cast object of type 'System.Windows.Forms.BindingSource' to type 'System.Data.DataTable'.

    Question

  • Hello everyone.

    I'm currently looking through the following instance of vb.net code in an attempt to better understand data binding:

    Sub:

    Public Shared Sub GoToLetterTypedInDataGridView(ByVal dgv As DataGridView, ByVal columnName As String, ByVal columnPosition As Integer, ByVal letterTyped As Char)
            Try
                Dim dt As DataTable = dgv.DataSource
                Dim letter As Char = letterTyped
                Dim dv As DataView = New DataView(dt)
                Dim hasCount As Boolean = False
    
                While (Not hasCount)
                    dv.Sort = columnName
                    dv.RowFilter = columnName & " like '" & letter & "%'"
                    If dv.Count > 0 Then
                        hasCount = True
                        Dim x As String = dv(0)(columnPosition).ToString()
                        Dim bs As New BindingSource
                        bs.DataSource = dt
                        dgv.BindingContext(bs).Position = bs.Find(columnName, x)
                        dgv.CurrentCell = dgv(0, bs.Position)
                    Else
                        If letter = "z" Then
                            letter = "a"
                        ElseIf letter = "Z" Then
                            letter = "A"
                        Else : letter = Chr(Asc(letter) + 1)
                        End If
                    End If
                End While
            Catch ex As Exception
                Dim stackframe As New Diagnostics.StackFrame(1)
                Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & "  Message was: '" & ex.Message & "'")
            End Try
        End Sub

    Call:

        Private Sub DataGridView3_KeyPress(sender As Object, e As KeyPressEventArgs) Handles DataGridView3.KeyPress
            If DataGridView3.RowCount > 0 Then
                GoToLetterTypedInDataGridView(DataGridView3, "Surname", 0, e.KeyChar)
            End If
        End Sub

    Whenever I run the code, I get the following error:

    An error occurred in routine, 'Start.GoToLetterTypedInDataGridView'.

     Message was: 'Unable to cast object of type 'System.Windows.Forms.BindingSource' to type 'System.Data.DataTable'.'

    Does anyone know how to resolve this problem? I am very grateful for your help. :)

    Wednesday, December 26, 2012 11:25 PM

Answers

  • Hello,

    I am suggesting taking a step back for a bit, download the following project and look how things are done. This is a master-detail relationship using 2 BindingSource, a temp DataSet with language extensions to keep things simple. There is one section of code well commented that shows how you can go overboard if you don't understand your data properly.

    Please note as is everything works from viewing master-details to working with underlying data viewed in two DataGridViews without the need to access the DataGridView events other than I make use of a custom DatePicker column.

    I think if you spend sometime with this, get an understanding you will be better off with your project.

    Last points

    • VS2010 (was originally VS2005, upgraded to VS2008 then VS2010) using Framework 4, Option Strict On, Option Infer On. Database is currently ms-access 2007, was just upgraded from ms-access 2000. Even if you are using a different database the methods remain the same, only the connection and syntax to SQL may differ.
    • Be sure to spend time examining the language extensions for the BindingSource component as this makes things much easier.


    KSG

    Friday, December 28, 2012 10:34 PM
    Moderator

All replies

  • What is your grid's data source? Is it a binding source or a data table? You have Dim dt As DataTable = dgv.DataSource  and dgv.BindingContext(bs).



    Visual C++ MVP

    Thursday, December 27, 2012 1:05 AM
  • Hello,

    Looks to me like there is some guessing happening here. A better idea is to know the data source of the DataGridView i.e. seems in this case a BindingSource and if so you should be passing the BindingSource component to this procedure. Also you need to know what is the DataSource of the BindingSource, it could be a DataTable, may be not. Also to keep code tight I would suggest setting Option Strict On at the top of the module containing this code and even better set Option Strict On under Project properties. In regards to creating a new BindingSource in the code above, there is no need if you pass in the BindingSource which is the DataSource of the DataGridView. Any time you are working in an event for keypress I would keep creation of objects to a minimum.


    KSG

    Thursday, December 27, 2012 12:12 PM
    Moderator
  •     

    Public Shared Sub GoToLetterTypedInDataGridView(ByVal dgv As DataGridView, ByVal columnName As String, ByVal columnPosition As Integer, ByVal letterTyped As Char) Try Dim bs As BindingSource = dgv.DataSource Dim ds As DataSet = bs.Current Dim dt As DataTable = ds.Tables("Customers") Dim letter As Char = letterTyped Dim dv As DataView = New DataView(dt) Dim hasCount As Boolean = False While (Not hasCount) dv.Sort = columnName dv.RowFilter = columnName & " like '" & letter & "%'" If dv.Count > 0 Then hasCount = True Dim x As String = dv(0)(columnPosition).ToString() Dim bs As New BindingSource bs.DataSource = dt dgv.BindingContext(bs).Position = bs.Find(columnName, x) dgv.CurrentCell = dgv(0, bs.Position) Else If letter = "z" Then letter = "a" ElseIf letter = "Z" Then letter = "A" Else : letter = Chr(Asc(letter) + 1) End If End If End While Catch ex As Exception Dim stackframe As New Diagnostics.StackFrame(1) Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & " Message was: '" & ex.Message & "'") End Try End Sub

    I'd like to thank both of you for your help -  It is very much appreciated. :)

    Above I have posted the altered code. The data source of the datagridview is indeed a binding source (and the data source of this binding source is a data set).

    Instead of expressing the data source variable as a data table, I now express it as a binding source. I then attempt to convert the binding source into a dataset and then I specify the exact table in this dataset as a separate variable (the dt variable).

    However, this produces the error: 'Unable to cast object of type 'System.Windows.Forms.BindingSource' to type 'System.Data.DataTable'.' Any ideas?

    Also, thanks for your advice on keeping the creation of objects to a minimum Kevininstructor - I think I will modify my code. :)

    Friday, December 28, 2012 6:48 PM
  • Hello,

    Which line is raising an exception?


    KSG

    Friday, December 28, 2012 7:04 PM
    Moderator
  • It appears on the line with the following code:

    Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & "  Message was: '" & ex.Message & "'")
    

    The header of the message is 'Exception was unhandled'.

    I have included an screenshot of the error below:

    http://www.majhost.com/gallery/cricky25/mocgallery/error.png

    Friday, December 28, 2012 7:57 PM
  • I would suggest removing the try/catch, run the project and let it break in debug mode to the offending line

    KSG

    Friday, December 28, 2012 8:54 PM
    Moderator
  • When I remove the try catch, the error message points to the code that calls the function, as seen in the screenshot below:

    http://www.majhost.com/gallery/cricky25/mocgallery/error1.png

    I'm wondering if I am improperly converting the 'bindingsource' variable to a data table.. :/

    Thanks for your help Kevininstructor. :)

    Friday, December 28, 2012 9:49 PM
  • Hello,

    I am suggesting taking a step back for a bit, download the following project and look how things are done. This is a master-detail relationship using 2 BindingSource, a temp DataSet with language extensions to keep things simple. There is one section of code well commented that shows how you can go overboard if you don't understand your data properly.

    Please note as is everything works from viewing master-details to working with underlying data viewed in two DataGridViews without the need to access the DataGridView events other than I make use of a custom DatePicker column.

    I think if you spend sometime with this, get an understanding you will be better off with your project.

    Last points

    • VS2010 (was originally VS2005, upgraded to VS2008 then VS2010) using Framework 4, Option Strict On, Option Infer On. Database is currently ms-access 2007, was just upgraded from ms-access 2000. Even if you are using a different database the methods remain the same, only the connection and syntax to SQL may differ.
    • Be sure to spend time examining the language extensions for the BindingSource component as this makes things much easier.


    KSG

    Friday, December 28, 2012 10:34 PM
    Moderator
  • Hello KevinInstructor

    I've looked through the example you've provided, and I've decided to take a step back in order to learn more about how data is used in Windows Forms. Thank you very much - your assistance has been invaluable. :)

    Sunday, December 30, 2012 6:07 PM