none
Binding source to ArrayList RRS feed

  • Question

  • Hi All

    I have a BindingSource bound to a DataTable(from sql database) with several columns

    I need to get all columns names from binding source and add them to an arraylist of names

    How to do that ?

    Thanks for help

    Wednesday, July 25, 2018 10:48 AM

All replies

  • Here is one way to do this.

    Dim columnNames() As String = CType(bsCustomers.DataSource, DataTable).
            Columns.Cast(Of DataColumn).
            Select(Function(c) c.ColumnName).ToArray()
    
    For Each col As String In columnNames
        Console.WriteLine(col)
    Next

    Edit, for a typed data set were there may be more than one table, here I target the first table.

    Dim cols = CType(bsCustomers.DataSource, DataSet).
        Tables(0).
        Columns.Cast(Of DataColumn).
        Select(Function(c) c.ColumnName).ToArray
    
    For Each col In cols
        Console.WriteLine(col)
    Next


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    Wednesday, July 25, 2018 11:09 AM
    Moderator
  • I dont think a bindingsource has columns.

    This should do it too

            Dim ColArray(DT.Columns.Count) As String
            For i = 0 To DT.Columns.Count
                ColArray(i) = DT.Columns(i).ColumnName
            Next


    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Wednesday, July 25, 2018 12:51 PM
  • I dont think a bindingsource has columns.

    This should do it too

            Dim ColArray(DT.Columns.Count) As String
            For i = 0 To DT.Columns.Count
                ColArray(i) = DT.Columns(i).ColumnName
            Next


    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    You are correct that a BindingSource component does not have columns, this is why I did a code sample that cast the underlying DataSource of a BindingSource to a DataTable which provides access to the DataColumnCollection. When writing code to access data one would set the BindingSource say in form Shown event then later on in another event of the form integrate properties of the underlying data source of access data e.g. CType(bsCustomers.Current,DataRowView).Row.Field(Of String)("FirstName") etc.

    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Wednesday, July 25, 2018 1:23 PM
    Moderator
  • Here is one way to do this.

    Dim columnNames() As String = CType(bsCustomers.DataSource, DataTable).
            Columns.Cast(Of DataColumn).
            Select(Function(c) c.ColumnName).ToArray()
    
    For Each col As String In columnNames
        Console.WriteLine(col)
    Next

    Edit, for a typed data set were there may be more than one table, here I target the first table.

    Dim cols = CType(bsCustomers.DataSource, DataSet).
        Tables(0).
        Columns.Cast(Of DataColumn).
        Select(Function(c) c.ColumnName).ToArray
    
    For Each col In cols
        Console.WriteLine(col)
    Next


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    Hi Karen, I am curious why you would want to do all this casting over a for block?

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Wednesday, July 25, 2018 5:01 PM
  • Here is one way to do this.

    Dim columnNames() As String = CType(bsCustomers.DataSource, DataTable).
            Columns.Cast(Of DataColumn).
            Select(Function(c) c.ColumnName).ToArray()
    
    For Each col As String In columnNames
        Console.WriteLine(col)
    Next

    Edit, for a typed data set were there may be more than one table, here I target the first table.

    Dim cols = CType(bsCustomers.DataSource, DataSet).
        Tables(0).
        Columns.Cast(Of DataColumn).
        Select(Function(c) c.ColumnName).ToArray
    
    For Each col In cols
        Console.WriteLine(col)
    Next


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    Hi Karen, I am curious why you would want to do all this casting over a for block?

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    I find that Lambda fits my style of coding. No different than if I had to do assertion right from the select. Here I use Console.WriteLine but in a real app I would be doing something for business requirements.

    CType(TblBookingBindingSource.DataSource, DataSet).
                Tables(0).
                Columns.Cast(Of DataColumn).
                Select(Function(c) c.ColumnName).ToList.ForEach(Sub(col) Console.WriteLine(col))
    It's kind of on the same lines as Enumerable.Range(1,40) to (1..40) <- (something coming soon)


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Wednesday, July 25, 2018 5:47 PM
    Moderator

  • Hi Karen, I am curious why you would want to do all this casting over a for block?

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Garry, think about it this way:  who knows where the binding came from?  All we know is that there is a BindingSource bound to a DataTable.  Maybe there is no other reference to that table in the current code.  This way the OP can just take the datasource and cast it back to a data table.  From that point on, there's really no practical difference between writing a loop over the table columns or using the LINQ extensions.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, July 25, 2018 6:34 PM
    Moderator

  • Hi Karen, I am curious why you would want to do all this casting over a for block?

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Garry, think about it this way:  who knows where the binding came from?  All we know is that there is a BindingSource bound to a DataTable.  Maybe there is no other reference to that table in the current code.  This way the OP can just take the datasource and cast it back to a data table.  From that point on, there's really no practical difference between writing a loop over the table columns or using the LINQ extensions.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Hmm... I just dont know, seems to me that unless you are using linq in many other subs or functions within the class that its not worth importing for this tiny thing.

    Also it looks like you would want to check for null reference before casting, where I believe a for block just wouldnt run if the count was <0. On that note I think my previous code should be more like this

            Dim ColArray(DT.Columns.Count - 1) As String
            For i = 0 To DT.Columns.Count - 1
                ColArray(i) = DT.Columns(i).ColumnName
            Next
    Certainly not trying to argue, but am I wrong thinking using linq for this is like reaching past a fly swatter and grabbing a bazooka to kill a fly?



    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Wednesday, July 25, 2018 8:12 PM

  • Hi Karen, I am curious why you would want to do all this casting over a for block?

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Garry, think about it this way:  who knows where the binding came from?  All we know is that there is a BindingSource bound to a DataTable.  Maybe there is no other reference to that table in the current code.  This way the OP can just take the datasource and cast it back to a data table.  From that point on, there's really no practical difference between writing a loop over the table columns or using the LINQ extensions.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Hmm... I just dont know, seems to me that unless you are using linq in many other subs or functions within the class that its not worth importing for this tiny thing.

    Also it looks like you would want to check for null reference before casting, where I believe a for block just wouldnt run if the count was <0. On that note I think my previous code should be more like this

            Dim ColArray(DT.Columns.Count - 1) As String
            For i = 0 To DT.Columns.Count - 1
                ColArray(i) = DT.Columns(i).ColumnName
            Next
    Certainly not trying to argue, but am I wrong thinking using linq for this is like reaching past a fly swatter and grabbing a bazooka to kill a fly?



    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    It's up to you in the end. I use Lambda pretty much all the time in ASP.NET, WPF, Entity Framework, traditional data containers and non-traditional both in C# and VB.NET which I'm much more comfortable with along with more flexibility.

    In regards to your example which does no casting, suppose the DataTable is loaded in form shown then in another completely different event you want to know the column names, DT is not available and if it is that means you declared it as a private variable where that is not a good way to code since we can cast the BindingSource on demand. Also there is no good reason in this case to size and then assign values to an array where the Framework does this for us via Lambda.

    In regards to importing, there is nothing to import (working from VS2015 on up)

    As stated above, it's your choice. 

    Edit for null check

    Public Class Form3
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If TblBookingBindingSource.DataSource Is Nothing Then
                ' decide how to handle
            Else
                CType(TblBookingBindingSource.DataSource, DataSet).
                    Tables(0).
                    Columns.Cast(Of DataColumn).
                    Select(Function(c) c.ColumnName).ToList.ForEach(Sub(col) Console.WriteLine(col))
            End If
        End Sub
        Private Sub TblBookingBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs) _
            Handles TblBookingBindingNavigatorSaveItem.Click
            Me.Validate()
            Me.TblBookingBindingSource.EndEdit()
            Me.TableAdapterManager.UpdateAll(Me.NorthWindAzure1DataSet)
        End Sub
        Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.TblBookingTableAdapter.Fill(Me.NorthWindAzure1DataSet.tblBooking)
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    Wednesday, July 25, 2018 9:00 PM
    Moderator
  • Certainly not trying to argue, but am I wrong thinking using linq for this is like reaching past a fly swatter and grabbing a bazooka to kill a fly?



    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    As Karen said, there's nothing to import when using any recent version.  It is simply using one of the tools at your disposal.  There's no overkill here by any means.  In fact, it could be seen as less code to write.  Personally I would have done it with a full LINQ statement; Karen likes extensions; you apparently like full blown loops.  Same thing in every case, its up to the developer and there isn't a right or wrong answer.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, July 25, 2018 9:50 PM
    Moderator
  • DT is not available and if it is that means you declared it as a private variable where that is not a good way to code since we can cast the BindingSource on demand. 

    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    I always declare a dataset in the class declaration then add datatables in the form load event. Are you suggesting that this is poor development? Have I been doing it wrong all this time? 

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Thursday, July 26, 2018 12:21 PM
  • DT is not available and if it is that means you declared it as a private variable where that is not a good way to code since we can cast the BindingSource on demand. 

    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    I always declare a dataset in the class declaration then add datatables in the form load event. Are you suggesting that this is poor development? Have I been doing it wrong all this time? 

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Never said what you are doing is wrong, everyone will have a different take on how to work with data and if it works for you fantastic,

    Here are two examples for what how I would be coding if still coding in Windows forms.

    https://code.msdn.microsoft.com/SQL-Server-application-1d1368bc?redir=0

    https://github.com/karenpayneoregon/SqlContraintViolations/blob/master/SQL_Server_VB/DataOperations.vb

    While the following is in C#, it still goes along with logic that is similar to the above, this time using Entity Framework.

    https://code.msdn.microsoft.com/Entity-Framework-in-764fa5ba?redir=0

    Back to VB.NET using MS-Access, follows the same path as the first two examples.

    https://code.msdn.microsoft.com/CRUD-data-operations-for-4783d8dd?redir=0


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Thursday, July 26, 2018 1:42 PM
    Moderator
  • Wow, Karen. Just wow. Looking at your examples just blows my mind. Complete with Frankensteining your own bindingsource... "IT'S ALIVE!...." *evil laughter*

    I have been spending at least an hour a day with a WPF solution, I do intend to leave Forms at some point. Seems to becoming clunky and dated and alot of unwanted UI flickering on some UI intensive forms is driving toward WPF dev.

    Thank you for your examples.


    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Thursday, July 26, 2018 4:04 PM