none
Retain DataGrid Sorting RRS feed

  • Question

  • hi

    i'm having a datagrid in VB Form, while initial form loading the grid loaded with Data.

    Requirement:

    if i clcked in any of the column header it needs to sorted and when i closed the form and get reopend, i need to retain the sorted column for the grid. whether it possible to fix by custom code, Please any one provide your suggestions


    - David

    Monday, September 11, 2017 11:09 AM

All replies

  • Is it a true DataGrid and therefore bound (With that there is no other way possible)

    Than check the datasource. 


    Success
    Cor

    Monday, September 11, 2017 12:41 PM
  • hi

    i'm having a datagrid in VB Form, while initial form loading the grid loaded with Data.

    Requirement:

    if i clcked in any of the column header it needs to sorted and when i closed the form and get reopend, i need to retain the sorted column for the grid. whether it possible to fix by custom code, Please any one provide your suggestions


    - David

    David,

    If it's databound then use the DataGridView.DataBindingComplete event to then iterate through the columns. For each column, look to see if it's the .SortedColumn and if so, then check the .SortOrder.

    Save those two settings any way you choose to then next time, once the data binding is complete (so that the columns have been created), restore it from those settings.

    You can use Application Settings for that or 'roll your own'.


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    • Edited by Frank L. Smith Monday, September 11, 2017 12:54 PM ...typo
    Monday, September 11, 2017 12:52 PM
  • Hi David,

    According to your description, you want to retain the datagridview sorting when you close the current form. Why you want to retain datagridview sorting when you close the current form? I can retain the datagridview sorting after reload.

    I don't find any way to save the current datagridview sorting, If other people have a good way, you can refer to.

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, September 12, 2017 7:19 AM
    Moderator
  • David,

    I've put something together for you (and others). I'll do part of this and you do the other part -- I'll explain:

    Just last week I was puzzled about knowing when to save and when to restore certain properties of a DataGridView. To further compound that, the "when" depends on whether or not the control is databound.

    My answer here is this: You make that determination.

    In the following, I've given you two methods that you'll work with, primarily at least, and that's a way to save the data (the data being the sorted column and the the sort order of a particular DGV) and a way to return what was saved as read-only properties.

    I have it all put together as an assembly (a .dll file) and in a minute I'll show the code for it. The .dll file is zipped up and uploaded here:

    https://fls.exavault.com/share/view/jcqa-6bobw6vt

    Download that and extract it somewhere. The data is saved as a binary file in the ApplicationData directory that's created if it doesn't exist. I'm using something that I created a while back to help with the binary serialization/deserialization as shown here.

    This assembly has that assembly embedded in it so that it all stays together.

    I'd like to get you to try it on an example program that's easy to make. You can then experiment with it to see just how it works.

    Start a new program and put a DataGridView (DataGridView1) on it and two buttons named "btn_SaveSortData" and "btn_LoadSortData". I have it set up to look like this:

    Now add a reference to the .dll that you extracted and the following code will do the rest:

    Option Strict On Option Explicit On Option Infer Off Imports DGV_ColumnProps.Info Public Class Form1 Private data As DGV_SpecialColumnProperties Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load DataGridView1.ColumnCount = 4 DataGridView1.ColumnHeadersVisible = True Dim columnHeaderStyle As New DataGridViewCellStyle() _ With {.BackColor = Color.Beige, _ .Font = New Font("Verdana", 9, FontStyle.Bold)} With DataGridView1 .SuspendLayout() .RowHeadersVisible = False .RowTemplate.Height = 35 .ColumnHeadersDefaultCellStyle = columnHeaderStyle With .Columns(0) .Name = "Recipe" .Width = 150 .DefaultCellStyle.WrapMode = DataGridViewTriState.True End With With .Columns(1) .Name = "Category" .Width = 150 .DefaultCellStyle.WrapMode = DataGridViewTriState.True End With With .Columns(2) .Name = "Main Ingredients" .Width = 175 .DefaultCellStyle.WrapMode = DataGridViewTriState.True End With With .Columns(3) .Name = "Rating" .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill End With .ResumeLayout() End With Dim row1() As String = _ {"Meatloaf", "Main Dish", "ground beef", "**"} Dim row2() As String = _ {"Key Lime Pie", "Dessert", "lime juice, evaporated milk", "****"} Dim row3() As String = {"Orange-Salsa Pork Chops", "Main Dish", _ "pork chops, salsa, orange juice", "****"} Dim row4() As String = {"Black Bean and Rice Salad", "Salad", _ "black beans, brown rice", "****"} Dim row5() As String = _ {"Chocolate Cheesecake", "Dessert", "cream cheese", "***"} Dim row6() As String = _ {"Black Bean Dip", "Appetizer", "black beans, sour cream", "***"} Dim rows() As Object = {row1, row2, row3, row4, row5, row6} Dim rowArray As String() For Each rowArray In rows DataGridView1.Rows.Add(rowArray) Next rowArray data = New DGV_SpecialColumnProperties data.LoadFromBinary() UpdateLoadButtonStatus() End Sub Private Sub _ btn_SaveSortData_Click(sender As System.Object, _ e As System.EventArgs) _ Handles btn_SaveSortData.Click data.SetData(DataGridView1) UpdateLoadButtonStatus() End Sub Private Sub _ btn_LoadSortData_Click(sender As System.Object, _ e As System.EventArgs) _ Handles btn_LoadSortData.Click Dim info As DGV_SpecialColumnProperties.ReturnData = _ data.GetData(DataGridView1) If info IsNot Nothing Then If info.SortedColumnIndex.HasValue Then If DataGridView1.ColumnCount >= info.SortedColumnIndex.Value Then Dim dgvc As DataGridViewColumn = DataGridView1.Columns(info.SortedColumnIndex.Value) If dgvc IsNot Nothing Then DataGridView1.Sort(dgvc, DirectCast(info.SortDirection, System.ComponentModel.ListSortDirection)) End If End If End If End If End Sub Private Sub UpdateLoadButtonStatus() btn_LoadSortData.Enabled = data.SavedDataExists(DataGridView1) End Sub End Class


    Now run it and you'll see this:

    I'll leave it up to you when you save the data, but know that it won't hurt to "save" anytime you choose. When I show the code in a minute you'll see why: If there's no column that's been sorted, it's not set/changed/or saved so running it really didn't do much of anything.

    That's also why you don't see the "Load Sort Data" button enabled although if there were a previously saved version it would be.

    Now I'll sort the data and save it:

    You can now see that the "Load" button is enabled. I'll now turn the program off and open it again:

    At this point I can now load the saved data and set the DataGridView based on what's returned by clicking the "Load" button:

    The DGV is sorted based on what was saved.

    The data that's returned (reference the form's code in the "Load" button event handler) is an instance of a class that's in the assembly:

            Public Class ReturnData
                Private _sortedColumnIndex As Nullable(Of Integer)
                Private _sortDirection As SortOrder = SortOrder.None
    
                Friend Sub New(ByVal idx As Nullable(Of Integer), _
                               ByVal order As SortOrder)
    
                    _sortedColumnIndex = idx
                    _sortDirection = order
    
                End Sub
    
                Public ReadOnly Property SortDirection As SortOrder
                    Get
                        Return _sortDirection
                    End Get
                End Property
    
                Public ReadOnly Property SortedColumnIndex As Nullable(Of Integer)
                    Get
                        Return _sortedColumnIndex
                    End Get
                End Property
    
                Public Overrides Function ToString() As String
    
                    If _sortedColumnIndex.HasValue Then
                        Return String.Format("Sorted Column Index: {0} | Sort Order: {1}", _
                                             _sortedColumnIndex.Value.ToString("n0"), _
                                             _sortDirection.ToString)
                    Else
                        Return "Sorted Column Index: N/A | Sort Order: N/A"
                    End If
    
                End Function
            End Class

    Please do note that the field and property for the sorted index is a Nullable(Of Integer) because it may not be sorted at all. Be sure to test that it .HasValue before you use it (that's also shown in the form's code earlier).

    *****

    This is what's in that assembly:

    http://www.fls-online.net/VBNet_Forum/09-12-17/DGV_ColumnProps_Assembly.htm

    If you'll look at the code for the "SetData" method, you can see what it does:

            Public Sub SetData(ByVal dgv As DataGridView, _
                               Optional ByVal saveData As Boolean = True)
    
                Try
                    If dgv Is Nothing Then
                        Throw New ArgumentNullException("DataGridView", "Cannot be null." & vbCrLf)
    
                    Else
                        Dim mb As System.Reflection.MethodBase = (New StackTrace).GetFrame(1).GetMethod
                        Dim callingFormName As String = mb.DeclaringType.Name
                        Dim dgvName As String = dgv.Name
    
                        If dgv.ColumnCount > 0 Then
                            Dim dgvc As DataGridViewColumn = dgv.SortedColumn
    
                            If dgvc IsNot Nothing Then
                                Dim idx As Integer = dgvc.Index
                                Dim order As SortOrder = dgv.SortOrder
    
                                Dim ci As CollectionItems = Item(callingFormName, dgvName, False)
    
                                If ci IsNot Nothing Then
                                    ci.SortDirection = order
                                    ci.SortedColumnIndex = idx
                                Else
                                    List.Add(New CollectionItems(callingFormName, dgvName, idx, order))
                                End If
    
                                If saveData Then
                                    SaveToBinary()
                                End If
                            End If
                        End If
                    End If
    
                Catch ex As Exception
                    Throw
                End Try
    
            End Sub

    Lastly, what's behind all of that is a collection class so you can save the sort data for as many DataGridView controls as you'd like.

    I hope you find this helpful. :)


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Tuesday, September 12, 2017 3:55 PM
  • Hi David,

    According to your description, you want to retain the datagridview sorting when you close the current form. Why you want to retain datagridview sorting when you close the current form? I can retain the datagridview sorting after reload.

    I don't find any way to save the current datagridview sorting, If other people have a good way, you can refer to.

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Cherry 

    I don't think so. There is written DATAGRID  that is a complete different control than a Datagridview. (Despite the marketing chit chat on MSDN)

    If you click in a windows forms Datagrid for instance on the header the presentation is sort based on the columnheader. The funny thing is that it is so much bound to the DataView that the last Sort parameters are stored in that. 


    Success
    Cor




    • Edited by Cor Ligthert Tuesday, September 12, 2017 6:54 PM
    Tuesday, September 12, 2017 6:52 PM