New to Telerik UI for WinForms? Download free 30-day trial

Server Side Paging in Virtual Grid


Product Version 2018.1 220
Product RadVirtualGrid for WinForms


RadVirtualGrid is a control providing a convenient UI to display only the visible part of a large set of data. By definition not all of that data needs to be available locally. The example in this article will handle a scenario of implementing a server side paging.


The data will be selected according to the current page index. The PageIndexChanging event is used to perform the new query. The example also mocks a repository in the RadVirtualGridRepository class working with OrderDataModel entities.

The animation below demonstrates the end result in RadVirtualGrid.

Figure 1: Server Side Paging

server-side-paging-in-virtualgrid 001

Form`s Setup and PageIndexChanging Event

public partial class ServerSidePagingVirtualGrid : Telerik.WinControls.UI.RadForm
    private VirtualGridRepository repository;
    private IList<OrderDataModel> data;
    public ServerSidePagingVirtualGrid()
        this.repository = new VirtualGridRepository();
        this.radVirtualGrid1.RowCount = this.repository.Orders.Count();
        this.radVirtualGrid1.ColumnCount = this.repository.ColumnNames.Length;
        this.radVirtualGrid1.EnablePaging = true;
        this.radVirtualGrid1.AutoSizeColumnsMode = Telerik.WinControls.UI.VirtualGridAutoSizeColumnsMode.Fill;
        this.radVirtualGrid1.CellValueNeeded += RadVirtualGrid1_CellValueNeeded;
        this.radVirtualGrid1.PageChanging += RadVirtualGrid1_PageChanging;
    private void RadVirtualGrid1_PageChanging(object sender, VirtualGridPageChangingEventArgs e)
    private void RadVirtualGrid1_CellValueNeeded(object sender, Telerik.WinControls.UI.VirtualGridCellValueNeededEventArgs e)
        if (e.ColumnIndex < 0)
        if (e.RowIndex == RadVirtualGrid.HeaderRowIndex)
            e.Value = this.repository.ColumnNames[e.ColumnIndex];
        if (e.RowIndex >= 0 && e.RowIndex < * (this.radVirtualGrid1.PageIndex + 1))
            int index = e.RowIndex - this.radVirtualGrid1.PageSize * this.radVirtualGrid1.PageIndex;
            e.Value =[index][e.ColumnIndex];
    private void SelectData(int pageIndex)
    { = this.repository.Orders.Skip(pageIndex * this.radVirtualGrid1.PageSize).Take(this.radVirtualGrid1.PageSize).ToList();

Public Class ServerSidePagingVirtualGrid
    Private repository As VirtualGridRepository
    Private data As IList(Of OrderDataModel)
    Public Sub New()
        Me.repository = New VirtualGridRepository()
        Me.RadVirtualGrid1.RowCount = Me.repository.Orders.Count()
        Me.RadVirtualGrid1.ColumnCount = Me.repository.ColumnNames.Length
        Me.RadVirtualGrid1.EnablePaging = True
        Me.RadVirtualGrid1.AutoSizeColumnsMode = Telerik.WinControls.UI.VirtualGridAutoSizeColumnsMode.Fill
        AddHandler Me.RadVirtualGrid1.CellValueNeeded, AddressOf RadVirtualGrid1_CellValueNeeded
        AddHandler Me.RadVirtualGrid1.PageChanging, AddressOf RadVirtualGrid1_PageChanging
    End Sub
    Private Sub RadVirtualGrid1_PageChanging(ByVal sender As Object, ByVal e As VirtualGridPageChangingEventArgs)
    End Sub
    Private Sub RadVirtualGrid1_CellValueNeeded(ByVal sender As Object, ByVal e As Telerik.WinControls.UI.VirtualGridCellValueNeededEventArgs)
        If e.ColumnIndex < 0 Then
        End If
        If e.RowIndex = RadVirtualGrid.HeaderRowIndex Then
            e.Value = Me.repository.ColumnNames(e.ColumnIndex)
        End If
        If e.RowIndex >= 0 AndAlso e.RowIndex < * (Me.RadVirtualGrid1.PageIndex + 1) Then
            Dim index As Integer = e.RowIndex - Me.RadVirtualGrid1.PageSize * Me.RadVirtualGrid1.PageIndex
            e.Value =
        End If
    End Sub
    Private Sub SelectData(ByVal pageIndex As Integer) = Me.repository.Orders.Skip(pageIndex * Me.RadVirtualGrid1.PageSize).Take(Me.RadVirtualGrid1.PageSize).ToList()
    End Sub
End Class

Mock Repository

public class VirtualGridRepository
    private Random rand = new Random();
    private IQueryable<OrderDataModel> orders;
    private string[] columnNames = new string[]
    public IQueryable<OrderDataModel> Orders
            if (this.orders == null)
            return this.orders;
    public string[] ColumnNames
            return this.columnNames;
    private IQueryable<OrderDataModel> GenerateData()
        IList<OrderDataModel> data = new List<OrderDataModel>();
        for (int i = 0; i < 1000; i++)
                new OrderDataModel
                    OrderId = i,
                    OrderDetails = "Order " + i,
                    ProductId = this.rand.Next(1000),
                    ClientId = this.rand.Next(1000),
                    ShipAddress = "Address " + i,
                    ShippingType = (ShippingType)rand.Next(3)
        this.orders = data.AsQueryable();
        return orders;

Public Class VirtualGridRepository
    Private rand As Random = New Random()
    Private _orders As IQueryable(Of OrderDataModel)
    Private _columnNames As String() = New String() {"OrderId", "OrderDetails", "ProductId", "ClientId", "ShipAddress", "ShippingType"}
    Public ReadOnly Property Orders As IQueryable(Of OrderDataModel)
            If Me._orders Is Nothing Then
            End If
            Return Me._orders
        End Get
    End Property
    Public ReadOnly Property ColumnNames As String()
            Return Me._columnNames
        End Get
    End Property
    Private Function GenerateData() As IQueryable(Of OrderDataModel)
        Dim data As IList(Of OrderDataModel) = New List(Of OrderDataModel)()
        For i As Integer = 0 To 1000 - 1
            data.Add(New OrderDataModel With {
                .OrderId = i,
                .OrderDetails = "Order " & i,
                .ProductId = Me.rand.[Next](1000),
                .ClientId = Me.rand.[Next](1000),
                .ShipAddress = "Address " & i,
                .ShippingType = CType(rand.[Next](3), ShippingType)
        Me._orders = data.AsQueryable()
        Return Orders
    End Function
End Class

Data Model

public class OrderDataModel
    public int OrderId { get; set; }
    public string OrderDetails { get; set; }
    public int ProductId { get; set; }
    public int ClientId { get; set; }
    public string ShipAddress { get; set; }
    public ShippingType ShippingType { get; set; }
    public object this[int i]
            switch (i)
                case 0:
                    return OrderId;
                case 1:
                    return OrderDetails;
                case 2:
                    return ProductId;
                case 3:
                    return ClientId;
                case 4:
                    return ShipAddress;
                case 5:
                    return ShippingType;
                    return string.Empty;
public enum ShippingType

Public Class OrderDataModel
    Public Property OrderId As Integer
    Public Property OrderDetails As String
    Public Property ProductId As Integer
    Public Property ClientId As Integer
    Public Property ShipAddress As String
    Public Property ShippingType As ShippingType
    Default Public ReadOnly Property Item(ByVal i As Integer) As Object
            Select Case i
                Case 0
                    Return OrderId
                Case 1
                    Return OrderDetails
                Case 2
                    Return ProductId
                Case 3
                    Return ClientId
                Case 4
                    Return ShipAddress
                Case 5
                    Return ShippingType
                Case Else
                    Return String.Empty
            End Select
        End Get
    End Property
End Class
Public Enum ShippingType
End Enum

A complete solution providing a C# and VB.NET project is available here.

See Also

In this article