Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Displaying Large Quantities of Data in Windows Controls

0.00/5 (No votes)
2 Jul 2009 1  
Demonstration of a technique for displaying very large quantities of data in Windows visual controls, using the ListView as an example.

Introduction

This article and accompanying code was written to demonstrate a technique for displaying very large quantities of data in a visual control, with very little performance degradation.

Background

It is a common situation in working with large quantities of data, where this data needs to be presented to the user. Lists and trees are often used for this purpose. Many times, the programmer attempts to load one of these controls with an entire data set. The problem arises when an increasing number of items are added to these controls; memory usage increases and performance decreases to the point that this solution is no longer acceptable.

This article presents a technique to display very large data sets with no performance degradation.

This technique could easily be adapted to a variety of .NET controls, as well as other platforms, such as Java Swing controls.

Strategy for Displaying Large Quantities of Data in a ListView

The approach for this example is to have a list control that will only contain data items that are visible to the user, not the entire data set. The existing .NET ListView component is used, coupled with a VScrollBar, which is 'manually' adjusted to reflect the quantity of data being represented. Since the ListView will only contain exactly the number of data items (ListViewItem) that can be displayed, the internal vertical scroll bar should never show. Therefore, it is necessary to manage a separate slider that accurately reflects the quantity of data being represented. This control can be thought of as being a sliding window that moves up and down over a large set of data.

As ListViewItems move out of view, they are deleted, and as new ones come into view, they are added, so that the list only contains a maximum of the number of items that can be viewed by the user.

Pieces of the Puzzle

The HighPerformanceListView is a new composite control that encapsulates a .NET ListView control and a VScrollBar control. This control can be added to the tool box and dropped onto a Form. To programmatically provide the data in a generic manner, this control uses an object implementing an IHighPerformanceListViewProvider interface. This object supplies the supplemental functionality needed by the ListView control to determine the column headers being displayed, and to provide ListViewItems that represent one item of data.

public interface IHighPerformanceListViewProvider
{
    List<ColumnHeaders> { get; }
    void SortDataList(int sortColumnNumber, SortOrder sortOrder);
    ListViewItem ConvertDataItemToListViewItem(int dataIndex);
    int DataCount { get; }
    HighPerformanceListView ControllingListView     { get; set; }
}

An abstract class, ListViewProviderBase, is provided, and implements the ControllingListView property of this interface.

Using the Code

The following code snippet demonstrates how to interact with the HighPerformanceListView control:

// Create a provider to supply data items, columns, etc. to
// the HighPerformanceListView
listViewProvider = new ListViewExampleProvider();

// Associate the new provider with the list view control:
highPerformanceListView.ListViewProvider = listViewProvider;

// List of data items to display in the list view control
// (This list is specific to the ListViewExampleProvider,
// and can be any type of data source in 'real-life'
List<DataItem> dataList;

// Set the application specific data list in the provider.
listViewProvider.DataList = dataList;

Points of Interest

Pass Through Events, Methods, and Properties

Since the HighPerformanceListView control is a UserControl that encapsulates a .NET ListView, the ListView specific events and properties were hidden. Pass-through properties, events, and methods had to be created for the user control that would pass-through information to the actual ListView control. The pass-through items do not represent a total recreation of those exposed by the ListView, but just enough to suffice for this example.

The pass-through items are organized in the HighPerformanceListView.PassThrough file, which contains a partial class definition of the list view class.

Example of Pass-Through Event
public event DrawListViewColumnHeaderEventHandler DrawColumnHeader
{
  // Pass the DrawColumnHeader event through
  // to the ListView.DrawColumnHeader
  add { listView.DrawColumnHeader += value; }
  remove { listView.DrawColumnHeader -= value; }
}

Sliding Window

The concept of the 'sliding window' is managed in the HighPerformanceListView by the following three variables:

// Index into the data list that represents the first item
// to be displayed in the list view.
// This represents the starting position of our
// sliding window moved over the data list.
private int displayStartIdx = 0;

// Number of rows from the data list that are being displayed
private int rowsDisplayed = 0;

// Maximum number of items (rows) that can be displayed in the list view
// (Depends on size of control on screen)
private int maxDisplayLines = 0;    

Refreshing Items in the ListView

As the control is resized, columns resorted, or view scrolled, the display items contained in the ListView need to be updated. The first attempt was made to optimize the process by either adding items coming into view, or deleting those items going out of view. This process caused unacceptable flicker.

Instead, each time items are added or deleted, the entire view is refreshed. This resulted in a vast improvement in visual performance. (See: HighPerformanceListView.RefreshListViewItems().)

Maintaining Multiple Selected Items Not in View

The current control does not track selected items that have gone out of view, but this could easily be added if needed.

ListView.VirtualMode Property

The purpose of this article was to present some ideas for handling large amounts of data, regardless of the control used. It should be noted that the ListView has a VirtualMode property. By using this property and supplying additional event code, similar performance increases can be achieved.

For an example of this method, see: ListView in VirtualMode and checkboxes By Alphons van der Heijden.

History

  • June 15, 2009: Initial creation of user control and example project.
  • July 01, 2009: Update article to reference Alphons van der Heijden's article on using ListView.VirtualMode.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here