Click here to Skip to main content
15,867,835 members
Articles / Desktop Programming / WPF
Tip/Trick

Data Virtualization using DataGrid

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
30 Oct 2018CPOL2 min read 22K   961   13   10
Data Virtualization example with a pagesize and async data request

Introduction

Using the DataGrid for millions of rows with a slow datasource will cause the user interface to freeze and give the end user a bad experience. UI virtualization comes automatically with the VirtualizationStackPanel inside the DataGrid, but Data Virtualization is not provided out of the box. Data Virtualization is the feature of providing only the data needed to present for the end user.

Typically, around 20-100 rows will be shown at a time. When the user starts scrolling, data virtualization is used to provide the requested rows. In this example, the pagesize is set to 20. What it means is that when the DataGrid is requesting a row, the next 20 rows will actually be loaded and prepared for presentation.

The idea is to use a CollectionView to encapsulate a DataTable. For the purpose, I have created a CollectionView called DataGridCollectionView. The DataGridCollectionView will be used as datasource for the ItemsSource property of the DataGrid. When the DataGrid is loaded, it will call out for row numbers 0, 1, 2, 3, etc. until the available space is filled. To be more effective than loading just one row at the time, the example here is using a pagesize so you batch load your rows.

Using the Code

The DataGridCollectionView comes with two events:

  • ItemsCount
  • ItemsRequest

The idea is that the ItemsCount is raised to tell the DataGrid how many rows can be expected.

The ItemsRequest is the actual request for items. The request is done in a background thread and has a startindex (the row number) and the number of items to provide. An Item is a DataRow in this example.

You hook it up like this:

C#
DataGridCollectionView dataGridCollectionView = new DataGridCollectionView(dataTable);
dataGridCollectionView.ItemsCount += OnItemsCount;
dataGridCollectionView.ItemsRequest += OnItemsRequest;

In the event handlers for this example, the count and DataRows are provided like this:

C#
private void OnItemsCount(DataGridCollectionView arg1, CountEventArgs arg2)
{
   arg2.Count = Count;
}

private void OnItemsRequest(DataGridCollectionView arg1, ItemsEventArgs arg2)
{
    int startIndex = arg2.StartIndex;
    int count = arg2.RequestedItemsCount;

    List<object> items = new List<object>();
    for (int i = startIndex; i < startIndex + count; i++)
    {
         DataRow row = dataTable.NewRow();

          row[0] = i.ToString();
          row[1] = rnd.Next(1000).ToString();
          row[2] = rnd.Next(1000).ToString();

          items.Add(row);
          //Simulating heavy loading time
          Thread.Sleep(10);                
     }

     arg2.SetItems(items);
}

As can be seen, you give back the rows in the SetItems method. The DataTable as you probably have guessed has 3 columns since the DataRow consists of 3 cells. You should easily be able to adapt this to your own needs.

The example is using the standard Model-View-ViewModel pattern.

The main XAML code defining the DataGrid.

XML
<DataGrid ItemsSource="{Binding TableSource, Mode=OneWay}" AutoGenerateColumns="False">
     <DataGrid.Columns>
          <DataGridTextColumn Binding="{Binding Path=[0]}" Header="Row number" />
          <DataGridTextColumn Binding="{Binding Path=[1]}" Header="column 2"/>
          <DataGridTextColumn Binding="{Binding Path=[2]}" Header="column 3"/>
     </DataGrid.Columns>
</DataGrid>

The ViewModel contains a property called TableSource that is the DataGridCollectionView.

A demo project is attached that should clear up most questions.

History

  • 29th October, 2018: Initial version

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Denmark Denmark
M.Sc computer science and physics

Worked with software development for many years.

Is now expert in WPF, databases, C#, .NET, ADO.NET, SQL server, ASP.NET, Android, blockchain and more Big Grin | :-D .

Comments and Discussions

 
QuestionScrollIntoView() doesn't work :( Pin
Valya-S7-Mar-19 7:10
Valya-S7-Mar-19 7:10 
AnswerRe: ScrollIntoView() doesn't work :( Pin
Carsten Breum28-Aug-19 23:42
professionalCarsten Breum28-Aug-19 23:42 
QuestionCould be 5 stars with support for updating rows Pin
Valya-S30-Oct-18 15:48
Valya-S30-Oct-18 15:48 
AnswerRe: Could be 5 stars with support for updating rows Pin
Carsten Breum30-Oct-18 19:46
professionalCarsten Breum30-Oct-18 19:46 
SuggestionMust override MoveCurrentToPosition() Pin
Valya-S30-Oct-18 15:06
Valya-S30-Oct-18 15:06 
GeneralRe: Must override MoveCurrentToPosition() Pin
Carsten Breum30-Oct-18 19:38
professionalCarsten Breum30-Oct-18 19:38 
QuestionWhere is mentioned demo project? Pin
Valya-S29-Oct-18 11:30
Valya-S29-Oct-18 11:30 
AnswerRe: Where is mentioned demo project? Pin
Member 244330629-Oct-18 12:20
Member 244330629-Oct-18 12:20 
GeneralRe: Where is mentioned demo project? Pin
Carsten Breum29-Oct-18 19:53
professionalCarsten Breum29-Oct-18 19:53 
GeneralRe: Where is mentioned demo project? Pin
Nelek30-Oct-18 20:01
protectorNelek30-Oct-18 20:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.