Server Side Paging in Virtual Grid
Environment
Product Version | 2018.1 220 |
Product | RadVirtualGrid for WinForms |
Description
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.
Solution
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.
Form`s Setup and PageIndexChanging Event
public partial class ServerSidePagingVirtualGrid : Telerik.WinControls.UI.RadForm
{
private VirtualGridRepository repository;
private IList<OrderDataModel> data;
public ServerSidePagingVirtualGrid()
{
InitializeComponent();
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.SelectData(this.radVirtualGrid1.PageIndex);
this.radVirtualGrid1.CellValueNeeded += RadVirtualGrid1_CellValueNeeded;
this.radVirtualGrid1.PageChanging += RadVirtualGrid1_PageChanging;
}
private void RadVirtualGrid1_PageChanging(object sender, VirtualGridPageChangingEventArgs e)
{
this.SelectData(e.NewIndex);
}
private void RadVirtualGrid1_CellValueNeeded(object sender, Telerik.WinControls.UI.VirtualGridCellValueNeededEventArgs e)
{
if (e.ColumnIndex < 0)
{
return;
}
if (e.RowIndex == RadVirtualGrid.HeaderRowIndex)
{
e.Value = this.repository.ColumnNames[e.ColumnIndex];
}
if (e.RowIndex >= 0 && e.RowIndex < this.data.Count * (this.radVirtualGrid1.PageIndex + 1))
{
int index = e.RowIndex - this.radVirtualGrid1.PageSize * this.radVirtualGrid1.PageIndex;
e.Value = this.data[index][e.ColumnIndex];
}
}
private void SelectData(int pageIndex)
{
this.data = 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()
InitializeComponent()
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
Me.SelectData(Me.RadVirtualGrid1.PageIndex)
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)
Me.SelectData(e.NewIndex)
End Sub
Private Sub RadVirtualGrid1_CellValueNeeded(ByVal sender As Object, ByVal e As Telerik.WinControls.UI.VirtualGridCellValueNeededEventArgs)
If e.ColumnIndex < 0 Then
Return
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.data.Count * (Me.RadVirtualGrid1.PageIndex + 1) Then
Dim index As Integer = e.RowIndex - Me.RadVirtualGrid1.PageSize * Me.RadVirtualGrid1.PageIndex
e.Value = Me.data(index)(e.ColumnIndex)
End If
End Sub
Private Sub SelectData(ByVal pageIndex As Integer)
Me.data = 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[]
{
"OrderId",
"OrderDetails",
"ProductId",
"ClientId",
"ShipAddress",
"ShippingType"
};
public IQueryable<OrderDataModel> Orders
{
get
{
if (this.orders == null)
{
GenerateData();
}
return this.orders;
}
}
public string[] ColumnNames
{
get
{
return this.columnNames;
}
}
private IQueryable<OrderDataModel> GenerateData()
{
IList<OrderDataModel> data = new List<OrderDataModel>();
for (int i = 0; i < 1000; i++)
{
data.Add(
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)
Get
If Me._orders Is Nothing Then
Me.GenerateData()
End If
Return Me._orders
End Get
End Property
Public ReadOnly Property ColumnNames As String()
Get
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)
})
Next
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]
{
get
{
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;
default:
return string.Empty;
}
}
}
}
public enum ShippingType
{
None,
Plane,
Truck
}
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
Get
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
None
Plane
Truck
End Enum
A complete solution providing a C# and VB.NET project is available here.