# Data Virtualization

Use data virtualization to load huge data in your WinForms datagrid without compromising with performance. Learn how to apply virtual mode to the WinForms datagrid.

## Content

Data virtualization refers to the process of loading data from remote sources in incremental manner, instead of loading it all at once. That is, in virtual mode, data is loaded on demand in chunks as the user scrolls the grid. Hence, the process is really useful while dealing with huge volumes of data and enables efficient loading of data in a shorter period of time.

There are two widely adopted approaches for data virtualization, pagination and cursor. In Pagination approach, a limit and offset parameter are send to the remote source to specify which portion of the data is requested. This approach returns the total amount of items available, so that the client may know how to retrieve the rest of the items. While, in Cursor approach, a token is send initially, which is null at first, to fetch the pages sequentially. In this case, the received page contains the token to the next one.

![](https://cdn.mescius.io/document-site-files/images/2f10b028-0ae8-4c29-a102-4d67578c339b/images/data-virtualization1.gif)

FlexGrid supports data virtualization and gives excellent performance while loading large data sets in real time. To implement virtual mode in the FlexGrid control, we use [C1DataCollection](https://developer.mescius.com/componentone/docs/services/online-datacollection/overview.html) library which provides data virtualization for any datagrid or list control.

The [C1DataCollection](/componentone/api/win/online-flexgrid/dotnet-api/C1.Win.FlexGrid.10/C1.Win.FlexGrid.C1FlexGridBase.DataSource.html) namespace provides [C1VirtualDataCollection](https://developer.mescius.com/componentone/docs/services/online-datacollection/C1.DataCollection~C1.DataCollection.C1VirtualDataCollection%601.html) and [C1CursorDataCollection](https://developer.mescius.com/componentone/docs/services/online-datacollection/C1.DataCollection~C1.DataCollection.C1CursorDataCollection%601.html) to implement pagination and cursor approach respectively. Both classes have an abstract **GetPageAsync()** method that must be implemented to return the items that will populate the collection. The base classes take the responsibility of caching the data as well as dispatching the requests of the pages according to a series of parameters that prevents too many pages to be requested together. In this topic, we are explaining the data virtualization and its implementation using the **C1VirtualDataCollection** class.

### Implement Data Virtualization

First of all, implement the **C1VirtualDataCollection** interface to override the [GetPageAsync](https://developer.mescius.com/componentone/docs/services/online-datacollection/C1.DataCollection~C1.DataCollection.C1CursorDataCollection%601~GetPageAsync.html) method as per your data. The GetPageAsync method of C1VirtualDataCollection returns the items in the page as well as a token to the next page. This method uses pageIndex, startingIndex, count, sortDescriptions, filterExpression and cancellation Token as parameters. The parameters pageIndex denotes the index of the requesting page, startingIndex denotes the index where the returned items will be inserted and count denotes the number of items to be returned. The **GetPageAsync** method returns total number of items (TotalCount) along with a list of the requested number of items (count) starting from an index (startingIndex).

```csharp
public class VirtualModeCollectionView : C1VirtualDataCollection<Customer>
{
    public int TotalCount { get; set; } = 1_000;
    protected override async Task<Tuple<int, IReadOnlyList<Customer>>> GetPageAsync(int pageIndex, int startingIndex, int count, IReadOnlyList<SortDescription> sortDescriptions = null, FilterExpression filterExpression = null, CancellationToken cancellationToken = default(CancellationToken))
    {
        await Task.Delay(500, cancellationToken);//Simulates network traffic.
        return new Tuple<int, IReadOnlyList<Customer>>(TotalCount, Enumerable.Range(startingIndex, count).Select(i => new Customer(i)).ToList());
    }
}
```

```vbnet
Public Class VirtualModeCollectionView
    Inherits C1VirtualDataCollection(Of Customer)
    Public Property TotalCount As Integer = 1_000
    Protected Overrides Async Function GetPageAsync(ByVal pageIndex As Integer, ByVal startingIndex As Integer, ByVal count As Integer, ByVal Optional sortDescriptions As IReadOnlyList(Of SortDescription) = Nothing, ByVal Optional filterExpression As FilterExpression = Nothing, ByVal Optional cancellationToken As CancellationToken = Nothing) As Task(Of Tuple(Of Integer, IReadOnlyList(Of Customer)))
        Await Task.Delay(500, cancellationToken)
        Return New Tuple(Of Integer, IReadOnlyList(Of Customer))(TotalCount, Enumerable.Range(startingIndex, count).[Select](Function(i) New Customer(i)).ToList())
    End Function
End Class
```

### Apply Data Virtualization to FlexGrid

To apply data virtualization on FlexGrid and populate it with the virtual data collection, create an object of [C1DataCollectionBindingList](https://developer.mescius.com/componentone/docs/services/online-datacollection/C1.DataCollection.BindingList~C1.DataCollection.BindingList_namespace.html) passing an instance of **VirtualModeCollectionView** and assign it to [DataSource](/componentone/docs/win/online-flexgrid/) property of the grid.

```csharp
private void Form1_Load(object sender, EventArgs e)
{
    var collectionView = new VirtualModeCollectionView();
    c1FlexGrid1.DataSource = new C1DataCollectionBindingList(collectionView);
    c1FlexGrid1.Visible = true;
}
```

```vbnet
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim collectionView As New VirtualModeCollectionView
    Dim data = New C1DataCollectionBindingList(collectionView)
    C1FlexGrid1.DataSource = New C1DataCollectionBindingList(collectionView)
    C1FlexGrid1.Visible = True
End Sub
```