In this part of tutorial we shall demonstrate work of the grid with large data volumes on the example of Instrument browser.

The business model already contains Instrument class. We shall add only one field (quoting currency) and create a lot of instruments in the application (e.g. 100000). For this purpose we shall modify Provider class and create an arbitrary list of instruments. As before, this list will be available as follows.

C# Copy imageCopy
IList<Instrument> instruments = Provider.Instance.Instruments;

Now let’s bind the grid to the data source. Memory consumption is one of the most important aspects of displaying large data volumes. When grid connects directly to application business logic, it significantly reduces memory consumption because there are no intermediate objects between the data layer and its presentation.

Let’s create InstrumentBrowser control and place it at the main panel. We shall add a panel for instrument filtering and searching and the grid to this control. We shall configure grid in the designer and link it to the data source.

C# Copy imageCopy
public partial class InstrumentBrowser : UserControl
{
    ...

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        //Bind grid to instruments in the run-time.
        if(!DesignMode)
        {
            grid.DataSource = Provider.Instance.Instruments;                
        }
    }
}

The screenshot below demonstrates the results of application work.

Instrument Browser 1

Let’s note an important detail. The collection of instruments contains about 100,000 elements. It is created when the application is launched. Total memory consumption of the entire application is about 45 MB. This collection is bound to the grid when Instrument browser tab is opened. After that, memory consumption increases to 59 MB. This means that the grid uses about 14 MB to display 100,000 elements. This amount of elements loads for about ½ seconds. These indicators demonstrate of grid performance with realistic numbers of instruments.

To navigate large data volumes a high performance filter is required. The grid provides a simple API for filter implementation.

C# Copy imageCopy
//Textbox event handlers
tbIsin.TextChanged += new System.EventHandler(tbIsin_TextChanged);
private void tbIsin_TextChanged(object sender, EventArgs e)
{
    _isinFilter = tbIsin.Text.ToUpper();
    grid.FilterRefresh();
}

tbCurrency.TextChanged += new System.EventHandler(tbCurrency_TextChanged);
private void tbCurrency_TextChanged(object sender, EventArgs e)
{
    _currencyFilter = tbCurrency.Text.ToUpper();
    grid.FilterRefresh();
}

//Grid firlter implementation
grid.Filter = new Filter(OnFilterData);

//Called when data is added or each time when the business object fires PropertyChanged notification
private bool OnFilterData(Row row)
{
    Instrument instrument = (Instrument) row.DataObject;
    bool visible = string.IsNullOrEmpty(tbIsin.Text) || instrument.Isin.Contains(tbIsin.Text.ToUpper());
    visible = visible && (string.IsNullOrEmpty(tbCurrency.Text) || instrument.Currency.Contains(tbCurrency.Text.ToUpper()));

    return !visible;
}

In this application many instruments have Weight, Shares, Capitalization values equaling 0. For more convenient data interpretation it is better not to display insignificant zeroes. Besides, it is better to add thousand separators for data formatting. Use of formats is the simplest way to implement this functionality. An example of creating a simple format for displaying digital information is provided below.

C# Copy imageCopy
public class NumericFormat : IFormat
{
    public string Format(IDataField dataField)
    {
        return Equals(0, dataField.Value) 
            ? string.Empty 
            : string.Format("{0:### ### ### ### ###}", dataField.Value);
    }

    public bool CanParse(string text, IDataField dataField)
    {
        return false;
    }

    public void Parse(string text, IDataField dataField)
    {
    }
}


public class Instrument
{
    ...

    [Format(typeof(NumericFormat))]
    public long Shares
    {
        get { return _shares; }
    }

    [Format(typeof(NumericFormat))]
    public double Capitalization
    {
        get { return _capitalization; }
    }
}


//Other way to setup a format:
Column column; 
column.Format = new NumericFormat();

Now the application will look as follows.

Instrument Browser 2