Results 1 to 13 of 13

Thread: [RESOLVED] DataGridView creation based on user choice of columns

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2005
    Posts
    606

    Resolved [RESOLVED] DataGridView creation based on user choice of columns

    I have an app that starts up with a datagridview on a Winform. The DGV show the user typical generic data so they may make a choice on which record thay want to choose. IE: Fname,Lname,StreetNo ect.. on full row select. No problem so far.

    I want the columns that are displayed to the user to be choosen by the user from a listbox on another form and then saved to my Access db. Still no problems

    This is where I'm stuck.
    I placed a bound DGV on my form and hide all the columns, then just change the visible property in a loop of the dgv columns collection, if the header text prop. matches my datafield that I read back.

    This method sucks as I have no control over the column index. The columns are created and they are filled with data, but that's about all I can say about this method.

    I've thought of creating a temp table then binding the DGV to it, but again the index would be only as good as the order the user choose to pick the fields and the order they're saved in.

    Here's how I'm currently do this, but there has to be a better way.
    Code:
     Private Sub CreateDGV()
           
            ' Input string from datatable
            Dim value As String = UserRow.FieldName
            ' Split on semicolon.
            Dim arr() As String = value.Split(";")
            ' Convert to List.
            Dim vals As List(Of String) = arr.ToList()
            ' Add the column to the dgv
            For Each val As String In vals
    
                For Each Col As DataGridViewColumn In Me.BidDataGridView.Columns
                    Dim ColName As String = Col.HeaderText
                    If ColName = val Then
                        Col.Visible = True
                        Me.BidDataGridView.Columns(0).Visible = False 'This is the only way I could find to hide column(0)
                    End If
                Next
            Next
        End Sub
    Any ideas out there how to do this differently?
    Life is about making some things happen, not waiting around for something to happen.

  2. #2
    Still learning kebo's Avatar
    Join Date
    Apr 2004
    Location
    Gardnerville,nv
    Posts
    3,758

    Re: DataGridView creation based on user choice of columns

    I have a form for my users that has a has 2 listboxes; one for columns that are not shown (hiddenColumns) and one for columns that are shown (shownColumns). Double clicking an item in either list moves the item to the other list. There are also buttons that allow the user to reorder the items in the shownColumns Listbox. When the form is closed, I build a List(of String) using the items in the shownColumns list box and I add the item in the order they appear in the list. Then when the datagrid form is shown, I use the list(of string) to hide or show the columns in the order choosen by the user....

    The code to update the grid looks like this...

    Code:
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
    'populate the grid with some columns....
            With Me.dGv.Columns
                Dim c As New DataGridViewTextBoxColumn()
                c.Name = "c1"
                .Add(c)
                c = New DataGridViewTextBoxColumn
                c.Name = "c2"
                .Add(c)
                c = New DataGridViewTextBoxColumn
                c.Name = "c3"
                .Add(c)
                c = New DataGridViewTextBoxColumn
                c.Name = "c4"
                .Add(c)
                c = New DataGridViewTextBoxColumn
                c.Name = "c5"
                .Add(c)
    
            End With
    'create the list of visible columns...
            Dim columnList As New List(Of String)
            columnList.Add("c2")
            columnList.Add("c5")
            columnList.Add("c1")
    
            Call updateGrid(columnList)
    
        End Sub
    
        Private Sub updateGrid(columnList As List(Of String))
            For Each col As DataGridViewColumn In dGv.Columns
    
                If columnList.Contains(col.Name) Then
                    col.Visible = True
                    col.DisplayIndex = columnList.IndexOf(col.Name)
    
                Else
    
                    col.Visible = False
                End If
            Next
        End Sub
    kevin
    Process control doesn't give you good quality, it gives you consistent quality.
    Good quality comes from consistently doing the right things.

    Vague general questions have vague general answers.
    A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.

    ______________________________
    Last edited by kebo : Now. Reason: superfluous typo's

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2005
    Posts
    606

    Re: DataGridView creation based on user choice of columns

    Kebo,
    Yea I also have two listboxs. One with available fields(the entire table) and one with columns to be displayed. 2 buttons to move fields back and forth. I guess I didn't think about a couple more button to change the order of the 2nd listbox.

    So the user has to choose which columns are displayed each time they want to view the datagridview? or are you saving the list
    Life is about making some things happen, not waiting around for something to happen.

  4. #4
    Still learning kebo's Avatar
    Join Date
    Apr 2004
    Location
    Gardnerville,nv
    Posts
    3,758

    Re: DataGridView creation based on user choice of columns

    I save the list.
    Process control doesn't give you good quality, it gives you consistent quality.
    Good quality comes from consistently doing the right things.

    Vague general questions have vague general answers.
    A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.

    ______________________________
    Last edited by kebo : Now. Reason: superfluous typo's

  5. #5
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,686

    Re: DataGridView creation based on user choice of columns

    Hello,

    Try this project
    Name:  M.jpg
Views: 296
Size:  23.1 KB

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2005
    Posts
    606

    Re: DataGridView creation based on user choice of columns

    Kevin,
    Sorry for the delay, having quite a time with Chrome browser.

    I'm developing with VS2010 with 4.0 framework. Looks like your project was developed with a later version of VS and the 4.5.2 framework.

    At any rate, what I was able to open, I looks like your changing the columns visible property based on if the columns name matches what is read out of the text file, is that correct?
    I seen something in there about the index also and I will investigate further today, now that I'm on a 32bit machine.
    Last night was a nightmare trying to open your project on a 64bit Vista box running 4.0 framework and VS2010. Even d/l 4.5.2 but the 64 bit thing got in the way trying to run the .exe out of the bin/debug
    Last edited by crater; Oct 15th, 2014 at 07:34 AM.
    Life is about making some things happen, not waiting around for something to happen.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2005
    Posts
    606

    Re: DataGridView creation based on user choice of columns

    ok so I almost got it work the way I want.
    I have 2 more questions:
    1) I have a fieldname(Archived) that appears in my list of string that has been saved to my db. The string is not in the last one yet the column with the same headertext is placed last. Any ideas why. I can move it up in the list, but it doesn't position correctly in the DGV.

    Please see image:

    2) Now that I can add fields and move them around. When I save the data (save button) how do I get the DGV to automatically hide or show the columns I changed. Right now I have to exit the application and restart to show the correct columns.
    Attached Images Attached Images  
    Life is about making some things happen, not waiting around for something to happen.

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2005
    Posts
    606

    Re: DataGridView creation based on user choice of columns

    Here is my code to build the list and then to deal with the DGV columns

    Code:
    Private Sub BuildColumnList()
    
            ' Input string from datatable
            Dim value As String = UserRow.FieldName
    
            ' Split on colon.
            Dim arr() As String = value.Split(";")
    
            ' Convert to List.
            Dim vals As List(Of String) = arr.ToList()
    
            ' Add the column to the dgv
            For Each val As String In vals
    
                ColumnList.Add(val)
    
            Next
        End Sub
    
        Private Sub CreateDGV(columnList As List(Of String))
    
            For Each col As DataGridViewColumn In BidDataGridView.Columns
    
                If columnList.Contains(col.HeaderText) Then
                    col.Visible = True
                    col.DisplayIndex = columnList.IndexOf(col.HeaderText)
                Else
                    col.Visible = False
                End If
            Next
    
        End Sub
    Life is about making some things happen, not waiting around for something to happen.

  9. #9
    Still learning kebo's Avatar
    Join Date
    Apr 2004
    Location
    Gardnerville,nv
    Posts
    3,758

    Re: DataGridView creation based on user choice of columns

    columnList needs to be an exposed (public) member of the options form. When you close the options form, grab the list, call a routine that will set the columns (pass the list to that routine) and save the list. When you need to show the options again, fetch the list, pass it to the options form, when the form closes, fetch the list....
    kevin
    Process control doesn't give you good quality, it gives you consistent quality.
    Good quality comes from consistently doing the right things.

    Vague general questions have vague general answers.
    A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.

    ______________________________
    Last edited by kebo : Now. Reason: superfluous typo's

  10. #10
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,686

    Re: DataGridView creation based on user choice of columns

    Quote Originally Posted by crater View Post
    Kevin,
    Sorry for the delay, having quite a time with Chrome browser.

    I'm developing with VS2010 with 4.0 framework. Looks like your project was developed with a later version of VS and the 4.5.2 framework.

    At any rate, what I was able to open, I looks like your changing the columns visible property based on if the columns name matches what is read out of the text file, is that correct?
    I seen something in there about the index also and I will investigate further today, now that I'm on a 32bit machine.
    Last night was a nightmare trying to open your project on a 64bit Vista box running 4.0 framework and VS2010. Even d/l 4.5.2 but the 64 bit thing got in the way trying to run the .exe out of the bin/debug
    Actually the project was originally done in VS2010 Framework 4 but all I have now is VS2012 and VS2013. In any event if you created a blank project, remove the form then add my files in it will work.

  11. #11

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2005
    Posts
    606

    Re: DataGridView creation based on user choice of columns

    I need some help here. I tryng to follow along with Kebo's logic.

    Code:
    'Make ColumnList a Public Member of Option Form
    Code:
     Public Property NewColumnList As New List(Of String)
    Code:
    Private Sub frmOptions_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    
            'Grab the list 
            CreateFieldList()
            BuildColumnList(FieldList)
    
            'Call routine on frmSearch that creates columns
            frmSearch.CreateDGVColumns(NewColumnList) 
    
        End Sub
    Code to build string from my listbox

    Code:
    Private Property FieldList As String
    Code:
     Private Function CreateFieldList()
    
            'Create a list of Fields to display in the search form that will be saved to db
    
            If lstboxUIFieldNames.Items.Count > 0 Then
                Dim StrArray(lstboxUIFieldNames.Items.Count)
                For item = 0 To lstboxUIFieldNames.Items.Count - 1
                    StrArray(item) = lstboxUIFieldNames.Items(item).ToString()
                Next
                FieldList = String.Join(";", StrArray).Trim(";")
            Else
                FieldList = String.Empty
            End If
            Return FieldList
    
        End Function
    Code to build list(of String) out of string

    Code:
    Private Sub BuildColumnList(FieldList)
    
            ' Input string from datatable
            Dim value As String = UserRow.FieldName
    
            ' Split on colon.
            Dim arr() As String = value.Split(";"c)
    
            ' Convert to List.
            Dim vals As List(Of String) = arr.ToList()
    
            ' Add the Column Name to the list
            For Each val As String In vals
    
                NewColumnList.Add(val)
    
            Next
    
        End Sub
    And finally the code to create the columns. This is in frmSearch

    Code:
    Private ColumnList As New List(Of String)
    Code:
     Public Sub CreateDGVColumns(columnList As List(Of String))
    
            'Hide all coulums in the DGV
            For Each Col As DataGridViewColumn In Me.BidDataGridView.Columns
                Col.Visible = False
            Next
    
            For Each col As DataGridViewColumn In BidDataGridView.Columns
    
                If columnList.Contains(col.HeaderText) Then
                    col.Visible = True
                    col.DisplayIndex = columnList.IndexOf(col.HeaderText)
                Else
                    col.Visible = False
                End If
            Next
    
        End Sub
    This all seems to work except my datagridview does not re-populate to columns even if I re-hide them.

    Any ideas
    Last edited by crater; Oct 16th, 2014 at 12:45 PM.
    Life is about making some things happen, not waiting around for something to happen.

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2005
    Posts
    606

    Re: DataGridView creation based on user choice of columns

    I think I have determined that my problem has something to do with the createDVGColumns sub. I created another sub, named it CreateNewDGVColumns(FieldList as(List of String)). To make sure I wasn't having variables messed with causing the problem. Change the call in frmOptions to CreateNewDGVColumns(ColumnList as List(of String)). I included a line to hide all the dgv columns and commented out the other code. The code to hide the columns doesn't even work, and I know it does in the Form Load method, it is the exact same code.
    So why can't I just change the visible property to false and true if there in my list? Almost like the dgv has to redraw or something like that. I read on MSDN about DGV.columns(xxx).visible property and it seems like everything I'm doing is correct \, but it just doesn't hide or show the columns that I had changed in the frmOptions.

    Sorry for being long winded but I'm getting very frustrated at this point. Stepping through code (f8) and everything seems to execute properly. Yet it doesn't work.
    Life is about making some things happen, not waiting around for something to happen.

  13. #13

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2005
    Posts
    606

    Re: DataGridView creation based on user choice of columns

    Finally got it to work. Thanks for the example Kebo and Kevin.
    My problem had to do with how I was creating the list(of string) in the options form.

    So here's the working code in case anyone else should need this.

    Code:
    Private Sub SelectFieldsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectFieldsToolStripMenuItem.Click
    
            Dim Options As frmOptions
            Options = New frmOptions(OneDataDataSet, ErvDataDataSet, UserName, UserID, UserRow, Me.Name)
    
            Dim result As DialogResult = Options.ShowDialog(Me)
    
            If result = Windows.Forms.DialogResult.Yes Then
    
                'Hide all coulums in the DGV
                For Each Col As DataGridViewColumn In Me.BidDataGridView.Columns
                    Col.Visible = False
                Next
    
                Try
                    For Each col As DataGridViewColumn In Me.BidDataGridView.Columns
    
                        If Options.ColList.Contains(col.Name) Then
                            col.Visible = True
                            col.DisplayIndex = Options.ColList.IndexOf(col.Name)
                        Else
                            col.Visible = False
                        End If
                    Next
    
                Catch ex As Exception
                    MsgBox(ex)
                End Try
    
            End If
    
        End Sub
    and the code in the Options form. Any question please ask.
    Code:
    Public Class frmOptions
        Private UserRow As ErvDataDataSet.UserOptionsRow
        Private IDFieldRow As ErvDataDataSet.IDFieldsRow
        Private Calling_Form As String
    
        Private NewColumnList As New List(Of String)
        Public Property ColList() As List(Of String)
            Get
                Return NewColumnList
            End Get
            Set(ByVal value As List(Of String))
    
            End Set
        End Property
    
        Sub New(ByVal OneDs As OneDataDataSet, ByVal ErvDs As ErvDataDataSet, ByVal Name As String, _
                 ByVal StaffID As Integer, ByVal Urow As DataRow, FormName As String)
    
            ' This call is required by the designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
            OneDataDataSet = OneDs
            ErvDataDataSet = ErvDs
            UserRow = Urow
    
            BidBindingSource.DataSource = OneDs
            IDStaffBindingSource.DataSource = OneDs
            IDStatusBindingSource.DataSource = OneDs
            IDProgramBindingSource.DataSource = OneDs
            Calling_Form = Microsoft.VisualBasic.Mid(FormName, 4)
    
            UserOptionsBindingSource.DataSource = ErvDs
            IDFieldsBindingSource.DataSource = ErvDs
    
        End Sub
    
        Private Sub btnSetRowColor_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSetRowColor.Click
    
            If GridColorDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
                UserRow.AlternatingRowColor = GridColorDialog.Color.ToArgb.ToString
            End If
    
        End Sub
    
        Private Sub frmOptions_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            Me.lstboxUIFieldNames.Items.Clear()
    
            Try
                'TODO: This line of code loads data into the 'ErvDataDataSet.IDFields' table. You can move, or remove it, as needed.
                Me.IDFieldsTableAdapter.Fill(Me.ErvDataDataSet.IDFields)
    
                ' Dim IDFieldRow As ErvDataDataSet.IDFieldsRow
                IDFieldRow = CType(CType(Me.IDFieldsBindingSource.Current, DataRowView).Row, ErvDataDataSet.IDFieldsRow)
    
            Catch ex As Exception
            End Try
    
            If UserRow.IsProgramNull Then
                UserRow.Program = ""
            Else
                ProgramComboBox.Text = UserRow.Program
            End If
    
            StaffNameComboBox.Text = UserRow.StaffName
            StatusComboBox.Text = UserRow.StatusID
    
            If UserRow.Archived = True Then
                ArchivedComboBox.Text = "Yes"
            ElseIf UserRow.Archived = False Then
                ArchivedComboBox.Text = "No"
            Else
                ArchivedComboBox.Text = "All"
            End If
    
            FillDBField_ListBox()
            FillUIFiled_ListBox_Default()
    
        End Sub
        Private Sub Save_User_Settings()
    
            Me.Validate()
            UserOptionsBindingSource.EndEdit()
            UserOptionsTableAdapter.Update(ErvDataDataSet)
    
        End Sub
    
    
        Private Sub FillDBField_ListBox()
    
            Try
                'Read from then IDField table
    
                ' Input string from datatable
                Dim value As String = IDFieldRow.FieldName
    
                ' Split on colon.
                Dim arr() As String = value.Split(";"c)
    
                ' Convert to List.
                Dim vals As List(Of String) = arr.ToList()
    
                ' Add the column to the dgv
                For Each val As String In vals
    
                    lstboxDBFieldName.Items.Add(val)
    
                Next
            Catch ex As Exception
                MsgBox(ex)
            End Try
    
        End Sub
    
        Private Sub FillUIFiled_ListBox_Default()
    
            'Read from the UserOptions Table
    
               ' Input string from datatable
            Dim value As String = UserRow.FieldName
    
            ' Split on colon.
            Dim arr() As String = value.Split(";"c)
    
            ' Convert to List.
            Dim vals As List(Of String) = arr.ToList()
    
            ' Add the column to the dgv
            For Each val As String In vals
    
                lstboxUIFieldNames.Items.Add(val)
    
            Next
    
        End Sub
    
    
        Private Sub btnClose_Click(sender As System.Object, e As System.EventArgs) Handles btnClose.Click
            Me.Close()
        End Sub
    
        Private Sub btnRemoveField_Click(sender As System.Object, e As System.EventArgs) Handles btnRemoveField.Click
    
            Dim selectedItems = (From i In lstboxUIFieldNames.SelectedItems).ToArray()
    
            For Each selectedItem In selectedItems
                lstboxDBFieldName.Items.Add(selectedItem)
                lstboxUIFieldNames.Items.Remove(selectedItem)
            Next
        End Sub
    
        Private Sub btnAddField_Click(sender As System.Object, e As System.EventArgs) Handles btnAddField.Click
    
            Dim selectedItems = (From i In lstboxDBFieldName.SelectedItems).ToArray()
    
            For Each selectedItem In selectedItems
                lstboxUIFieldNames.Items.Add(selectedItem)
                lstboxDBFieldName.Items.Remove(selectedItem)
            Next
        End Sub
    
    
        Private Fieldlist As String
    
        Private Function CreateFieldList()
    
            'Create a list of Fields to display in the search form that will be saved to db
    
            If lstboxUIFieldNames.Items.Count > 0 Then
                Dim StrArray(lstboxUIFieldNames.Items.Count)
                For item = 0 To lstboxUIFieldNames.Items.Count - 1
                    StrArray(item) = lstboxUIFieldNames.Items(item).ToString()
                Next
                Fieldlist = String.Join(";", StrArray).Trim(";"c)
            Else
                Fieldlist = String.Empty
            End If
            Return Fieldlist
    
        End Function
    
    
        Private Sub BuildColumnList(FieldList)
    
            ' Input string from datatable
            Dim value As String = FieldList
    
            ' Split on colon.
            Dim arr() As String = value.Split(";"c)
    
            ' Convert to List.
            Dim vals As List(Of String) = arr.ToList()
    
            ' Add the Column Name to the list
            For Each val As String In vals
    
                NewColumnList.Add(val)
    
            Next
    
        End Sub
        Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
    
            CreateFieldList()
            BuildColumnList(Fieldlist)
    
    
            'Set values in Dataset
            UserRow.FieldName = FieldList
            UserRow.Program = Me.ProgramComboBox.SelectedValue
            UserRow.SearchIn = Me.SearchInComboBox.SelectedItem
            UserRow.Archived = Me.ArchivedComboBox.SelectedItem
            UserRow.StaffID = Me.StaffNameComboBox.SelectedValue
            UserRow.FormName = Calling_Form
    
            'Save to db
            Me.Validate()
            Me.UserOptionsBindingSource.EndEdit()
            Me.ErvTableAdapterManager.UpdateAll(Me.ErvDataDataSet)
            Me.UserOptionsBindingSource.DataSource = ErvDataDataSet.UserOptions
    
    
    
        End Sub
    
    
    
    
        Private Sub btnUp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUp.Click
    
            'Make sure our item is not the first one on the list.  
    
            If lstboxUIFieldNames.SelectedIndex > 0 Then
    
                Dim I = lstboxUIFieldNames.SelectedIndex - 1
    
                lstboxUIFieldNames.Items.Insert(I, lstboxUIFieldNames.SelectedItem)
    
                lstboxUIFieldNames.Items.RemoveAt(lstboxUIFieldNames.SelectedIndex)
    
                lstboxUIFieldNames.SelectedIndex = I
    
            End If
    
        End Sub
    
        Private Sub btnDn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDn.Click
    
            'Make sure our item is not the last one on the list.  
    
            If lstboxUIFieldNames.SelectedIndex < lstboxUIFieldNames.Items.Count - 1 Then
    
                'Insert places items above the index you supply, since we want  
    
                'to move it down the list we have to do + 2  
    
                Dim I = lstboxUIFieldNames.SelectedIndex + 2
    
                lstboxUIFieldNames.Items.Insert(I, lstboxUIFieldNames.SelectedItem)
    
                lstboxUIFieldNames.Items.RemoveAt(lstboxUIFieldNames.SelectedIndex)
    
                lstboxUIFieldNames.SelectedIndex = I - 1
    
            End If
    
        End Sub
    
    
    
    End Class
    Life is about making some things happen, not waiting around for something to happen.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width