This is a migrated thread and some comments may be shown as answers.

Sorting and filtering not working

4 Answers 324 Views
VirtualGrid
This is a migrated thread and some comments may be shown as answers.
Ian
Top achievements
Rank 2
Bronze
Iron
Iron
Ian asked on 31 Oct 2018, 08:57 AM

I can't seem to make filtering and sorting work with my RadVirtualGrid. The control itself does the job mostly fine - lightning fast loading of 2000+ rows of data.

I've reduced it to a simple example: a single form with a single RadVirtualGrid, which uses all the code form the online example, 

Only different between my simple example and the documented one is that I don't get the objects from a DB - just make them.

The grid populates fine - it's just the filter/sort which does nothing.

I can get the more advanced filter/sort option events to fire OK, but I only need the simple stuff - single column sorts and single column filtering

There's obviously something really simple I've missed -any suggestions ?

 

Code is:

Imports Telerik.WinControls.UI

Public Class RadForm1
    Private columnNames As String() = New String() {"CompanyName", "ContactName", "ContactTitle", "Address", "PostalCode"}
    ' Dim connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
    "..\..\DataSources\Nwind.mdb;Persist Security Info=True"   - NOT USED
    Private data As New List(Of Customer)()
    Private Sub VirtualGridPopulatingWithData_Load(sender As Object, e As EventArgs) Handles Me.Load
        AddHandler Me.RadVirtualGrid1.CellValueNeeded, AddressOf radVirtualGrid1_CellValueNeeded
        Me.RadVirtualGrid1.ColumnCount = columnNames.Length
        SelectData()
    End Sub
    Private Sub radVirtualGrid1_CellValueNeeded(sender As Object, e As VirtualGridCellValueNeededEventArgs)
        If e.ColumnIndex < 0 Then
            Return
        End If
        If e.RowIndex = RadVirtualGrid.HeaderRowIndex Then
            e.Value = columnNames(e.ColumnIndex)
        End If
        If e.RowIndex < 0 Then
            e.FieldName = columnNames(e.ColumnIndex)
        End If
        If e.RowIndex >= 0 AndAlso e.RowIndex < data.Count Then
            e.Value = data(e.RowIndex)(e.ColumnIndex)
        End If
    End Sub
    Private Sub SelectData()

        data = Customer.makeData

        Me.RadVirtualGrid1.RowCount = data.Count
    End Sub
End Class
Public Class Customer

    Public Shared Function makeData() As List(Of Customer)
        Dim someCustomers As New List(Of Customer)
        someCustomers.Add(New Customer("1", "Company1", "Fred", "Mr", "addr1", "np7"))
        someCustomers.Add(New Customer("2", "Company2", "Bill", "Mr", "addr2", "np8"))
        someCustomers.Add(New Customer("3", "Company3", "Andi", "Mrs", "addr0", "np3"))

        Return someCustomers
    End Function

    Public Sub New(customerId As String, companyName As String, contactName As String,
    contactTitle As String, address As String, postalCode As String)
        Me.CustomerId = customerId
        Me.CompanyName = companyName
        Me.ContactName = contactName
        Me.ContactTitle = contactTitle
        Me.Address = address
        Me.PostalCode = postalCode
    End Sub

    Public Property CustomerId() As String
        Get
            Return m_CustomerId
        End Get
        Set(value As String)
            m_CustomerId = value
        End Set
    End Property
    Private m_CustomerId As String
    Public Property CompanyName() As String
        Get
            Return m_CompanyName
        End Get
        Set(value As String)
            m_CompanyName = value
        End Set
    End Property
    Private m_CompanyName As String
    Public Property ContactName() As String
        Get
            Return m_ContactName
        End Get
        Set(value As String)
            m_ContactName = value
        End Set
    End Property
    Private m_ContactName As String
    Public Property ContactTitle() As String
        Get
            Return m_ContactTitle
        End Get
        Set(value As String)
            m_ContactTitle = value
        End Set
    End Property
    Private m_ContactTitle As String
    Public Property Address() As String
        Get
            Return m_Address
        End Get
        Set(value As String)
            m_Address = value
        End Set
    End Property
    Private m_Address As String
    Public Property PostalCode() As String
        Get
            Return m_PostalCode
        End Get
        Set(value As String)
            m_PostalCode = value
        End Set
    End Property
    Private m_PostalCode As String

    Default Public ReadOnly Property Item(i As Integer) As String
        Get
            Select Case i
                Case 0
                    Return CompanyName
                Case 1
                    Return ContactName
                Case 2
                    Return ContactTitle
                Case 3
                    Return Address
                Case 4
                    Return PostalCode
                Case Else
                    Return [String].Empty
            End Select
        End Get
    End Property
End Class

4 Answers, 1 is accepted

Sort by
0
Czeshirecat
Top achievements
Rank 2
Iron
Iron
answered on 01 Nov 2018, 10:01 AM
01.// in grid initialization
02.Grid.AllowSorting = true;
03. 
04.//initialize sort order
05.var descriptor = new SortDescriptor
06. {
07.    PropertyName = "Surname",
08.    Direction = ListSortDirection.Ascending
09.  };
10. Grid.SortDescriptors.Add(descriptor);
11.Grid.SortChanged += OnMasterViewSortChanged;
12. 
13.// my code is used to fire off running a sql query so it creates the 'order by' parameter, but
14.// you can adapt it for whatever you need to sort your own table
15.// property SortOrder is the finished string. If that's blank then in my code I set it to a default eg "surname asc"
16.protected void OnMasterViewSortChanged(object sender, VirtualGridEventArgs e)
17.    {
18.        // expression returns the grid column header name and whether its asc or desc
19.        var sortExpression = Grid.SortDescriptors.Expression;
20. 
21.// if it's empty then it's the non asc/desc state of a column and requires some kind of default, or just don't sort
22.        if (!string.IsNullOrWhiteSpace(sortExpression))
23.        {
24.          var direction = "";
25.          var idx = sortExpression.IndexOf(" ASC", StringComparison.InvariantCultureIgnoreCase);
26.          if (idx > -1) direction = "ASC";
27.          else
28.          {
29.            idx = sortExpression.IndexOf(" DESC", StringComparison.InvariantCultureIgnoreCase);
30.            if (idx > -1) direction = "DESC";
31.          }
32. 
33.          if (idx > -1)
34.            sortExpression = sortExpression.Substring(0, idx).Trim();
35. 
36.          var colIndex = _fieldHeaders.IndexOf(sortExpression);
37. 
38.          if (string.IsNullOrWhiteSpace(sortExpression) || colIndex < 0)
39.            return;
40. 
41.          GetColumnInfo(colIndex, out var fieldName);
42. 
43.          if (NonSortableColumnList.Contains(fieldName))
44.          {
45.            return;
46.          }
47. 
48.          var sortOrder = $"{fieldName} {direction}";
49.          if (sortOrder == SortOrder) return;
50. 
51.          SortOrder = sortOrder;
52.        }
53.        else return;
54. 
55.    }
0
Ian
Top achievements
Rank 2
Bronze
Iron
Iron
answered on 01 Nov 2018, 10:11 AM

The key bit of information seems to be:

Sorting and filtering only work if you make them work.

There is NO built-in function for this, which is, I think, what I was expecting!

@Telerik - it would be good to put this into the 'sort/filter' bits of the documentation: it's really important!

Thanks @Czeshirecat as well - this really helped!

0
Accepted
Dess | Tech Support Engineer, Principal
Telerik team
answered on 01 Nov 2018, 10:40 AM
Hello, Ian, 

RadVirtualGrid is a grid component developed on top of Telerik Presentation Framework which provides a convenient way to implement your own data management operations and optimizes the performance when interacting with large amounts of data. RadVirtualGrid supports data sorting. Set the RadVirtualGrid.AllowSorting property to true in order to enable the user sorting feature. It is necessary to handle the SortChanged event which is fired once the SortDescriptors collection is changed. In the event handler you should extract the sorted data from the external data source. A sample approach is demonstrated in the following help article: https://docs.telerik.com/devtools/winforms/virtualgrid/sorting/sorting

RadVirtualGrid supports data filtering. Set the RadVirtualGrid.AllowFiltering property to true. It is necessary to handle the FilterChanged event which is fired once the FilterDescriptors collection is changed. In the event handler you should extract the filtered data from the external data source. You can refer to the online documentation: https://docs.telerik.com/devtools/winforms/virtualgrid/filtering/filtering

Our Demo application >> VirtualGrid examples are also quite useful for getting started experience with RadVirtualGrid

@Claire, thank you for your reply. I have also updated your Telerik points for the community effort.

I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Ian
Top achievements
Rank 2
Bronze
Iron
Iron
answered on 25 Jan 2019, 09:16 AM

So i finally figured out a way of doing this simply, and I thought others might like the code.

I have a large grid, with columns which are set at runtime, and might be >50, so sorting might be a problem.

I have all the data stored in a list called allDiagrams:

  Private Sub gvVirtual_SortChanged(sender As Object, e As VirtualGridEventArgs) Handles gvVirtual.SortChanged
        'resort the data
        Dim sortExpression As String = gvVirtual.SortDescriptors.Expression
        'sort expression is of the form 'columnName' (space) 'ASC' or 'DESC'
    'Should have a better way of  detecting column names which have spaces....but none of mine do.
        Dim strs As String() = sortExpression.Split(" ")
        If strs.Length = 2 Then
            'simple case
            allDiagrams.OrderBy(Function(x) x.GetType().GetProperty(strs(0)).GetValue(x)).ToList()
            If strs(1) <> "ASC" Then
                allDiagrams.Reverse()
            End If
        End If
    End Sub

This means I can have any number of column names, and the sort will always work.

(how did we write code before we could Google for answers...)

Tags
VirtualGrid
Asked by
Ian
Top achievements
Rank 2
Bronze
Iron
Iron
Answers by
Czeshirecat
Top achievements
Rank 2
Iron
Iron
Ian
Top achievements
Rank 2
Bronze
Iron
Iron
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or