New to Telerik UI for WinFormsStart a free 30-day trial

Summary Rows

Updated over 6 months ago

The purpose of this article is to demonstrate a sample approach how you can implement a scenario in which RadVirtualGrid displays summary rows.

Figure 1: Summary Rows

WinForms RadVirtualGrid Summary Rows

We will use a sample DataTable to populate the RadVirtualGrid with data by using the CellValueNeeded event. In a List of integer values, we will store the row indices at which the summary rows will be placed. Thus, in the CellValueNeeded event for the specific row index that is related to a summary row, we will calculate the summary value. The CellFormatting event will be used to apply different style for the summary cells. Finally, subscribe to the CellValuePushed event where you should modify the DataTable value for the associated cell. In order to update the summary values, call the RadVirtualGrid.TableElement.SynchronizeRows method.

You can find below a complete code snippet which result is illustrated on the above figure:

C#
        
private DataTable table = new DataTable();
private List<int> summaryRowIndices = new List<int>();
        
public VirtualGridSummaryRows()
{
    InitializeComponent();
    
    this.table = this.GenerateData();
    
    this.summaryRowIndices.AddRange(new int[] { 5, 11, 14, 20, 25, 35 });
    
    this.radVirtualGrid1.RowCount = table.Rows.Count + summaryRowIndices.Count;
    this.radVirtualGrid1.ColumnCount = table.Columns.Count;
    this.radVirtualGrid1.CellValueNeeded += VirtualGridElement_CellValueNeeded;
    this.radVirtualGrid1.CellValuePushed += VirtualGridElement_CellValuePushed;
    this.radVirtualGrid1.CellFormatting += radVirtualGrid1_CellFormatting;
}
        
private DataTable GenerateData()
{
    DataTable table = new DataTable();
    
    for (int i = 0; i < 4; i++)
    {
        table.Columns.Add("Column" + i, typeof(decimal));
    }
    
    for (int i = 0; i < 30; i++)
    {
        table.Rows.Add(i, i, i, i);
    }
    
    return table;
}
        
private void VirtualGridElement_CellValueNeeded(object sender, VirtualGridCellValueNeededEventArgs e)
{
    if (e.RowIndex < 0 && e.ColumnIndex >= 0)
    {
        if (e.RowIndex == RadVirtualGrid.HeaderRowIndex)
        {
            e.Value = table.Columns[e.ColumnIndex].ColumnName;
        }
    }
    else if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
    {
        if (this.IsSummaryRow(e.RowIndex))
        {
            e.Value = this.GetSummaryValue(e.RowIndex, e.ColumnIndex);
        }
        else
        {
            e.Value = this.table.Rows[this.GetDataSourceRowIndex(e.RowIndex)][e.ColumnIndex];
        }
    }
}
        
private void radVirtualGrid1_CellFormatting(object sender, VirtualGridCellElementEventArgs e)
{
    if (this.IsSummaryRow(e.CellElement.RowIndex))
    {
        e.CellElement.BackColor = Color.LightBlue;
        e.CellElement.DrawFill = true;
        e.CellElement.GradientStyle = GradientStyles.Solid;
    }
    else
    {
        e.CellElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
        e.CellElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local);
        e.CellElement.ResetValue(LightVisualElement.GradientStyleProperty, ValueResetFlags.Local);
    }
}
        
private void VirtualGridElement_CellValuePushed(object sender, VirtualGridCellValuePushedEventArgs e)
{
    this.table.Rows[this.GetDataSourceRowIndex(e.RowIndex)][e.ColumnIndex] = e.Value;
    this.radVirtualGrid1.TableElement.SynchronizeRows();
}
        
private bool IsSummaryRow(int virtualGridRowIndex)
{
    return this.summaryRowIndices.BinarySearch(virtualGridRowIndex) >= 0;
}
        
private int GetDataSourceRowIndex(int virtualGridRowIndex)
{
    int result = virtualGridRowIndex;
    
    for (int i = 0; i < this.summaryRowIndices.Count; i++)
    {
        if (virtualGridRowIndex >= this.summaryRowIndices[i])
        {
            result--;
        }
        else
        {
            break;
        }
    }
    
    return result;
}
        
private object GetSummaryValue(int virtualGridRowIndex, int virtualGridcolumnIndex)
{
    int index = this.summaryRowIndices.BinarySearch(virtualGridRowIndex);
    
    if (index < 0)
    {
        return null;
    }
    
    int startIndex = 0;
    int endIndex = 0;
    
    if (index == 0)
    {
        startIndex = 0;
        endIndex = this.summaryRowIndices[index] - 1;
    }
    else
    {
        startIndex = this.summaryRowIndices[index - 1] + 1;
        endIndex = this.summaryRowIndices[index] - 1;
    }
    
    startIndex = this.GetDataSourceRowIndex(startIndex);
    endIndex = this.GetDataSourceRowIndex(endIndex);
    
    return this.ExecuteSummaryFunction(startIndex, endIndex, virtualGridcolumnIndex);
}
        
private object ExecuteSummaryFunction(int startRowIndex, int endRowIndex, int columnIndex)
{
    switch (columnIndex)
    {
        case 0:
            decimal sum = 0;
            
            for (int i = startRowIndex; i <= endRowIndex; i++)
            {
                sum += (decimal)this.table.Rows[i][columnIndex];
            }
            
            return "Sum = " + sum;
        case 1:
            decimal avgSum = 0;
            
            for (int i = startRowIndex; i <= endRowIndex; i++)
            {
                avgSum += (decimal)this.table.Rows[i][columnIndex];
            }
            
            return "Avg = " + (avgSum / (endRowIndex - startRowIndex + 1));
        case 2:
            decimal min = int.MaxValue;
            
            for (int i = startRowIndex; i <= endRowIndex; i++)
            {
                min = Math.Min(min, (decimal)this.table.Rows[i][columnIndex]);
            }
            
            return "Min = " + min;
        case 3:
            decimal max = int.MinValue;
            
            for (int i = startRowIndex; i <= endRowIndex; i++)
            {
                max = Math.Max(max, (decimal)this.table.Rows[i][columnIndex]);
            }
            
            return "Max = " + max;
        default:
            return null;
    }
}

See Also

In this article
See Also
Not finding the help you need?
Contact Support