This is a migrated thread and some comments may be shown as answers.

SummaryRowsBottom

4 Answers 293 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Zerka
Top achievements
Rank 1
Zerka asked on 25 Nov 2010, 03:11 PM
Hi,

I have 2 SummaryRowsBottom in my RAdGridView. In first SummaryRowsBottom, I am showing the sum of each column.  The second SummaryRowsBottom is pouplating from the database. This all is working fine.

Now, I want to add 1 more SummaryRowsBottom and I want to show the difference of values of above 2 SummaryRowsBottom. Can you please help me how to do this?

Regards!

4 Answers, 1 is accepted

Sort by
0
Accepted
Emanuel Varga
Top achievements
Rank 1
answered on 25 Nov 2010, 03:47 PM
Hello,

A not so very clean way to do this could be the following:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Telerik.WinControls.UI;
 
public partial class Form1 : Form
{
    private RadGridView radGridView1;
    private GridViewSummaryItem calculatedSummaryItem, summaryItem1, summaryItem2;
    private Dictionary<GridViewSummaryItem, object> values = new Dictionary<GridViewSummaryItem, object>();
 
    public Form1()
    {
        this.Size = new Size(800, 600);
        InitializeComponent();
        this.Controls.Add(radGridView1 = new RadGridView());
        radGridView1.Dock = DockStyle.Fill;
        radGridView1.AutoSizeColumnsMode
            = GridViewAutoSizeColumnsMode.Fill;
 
        radGridView1.DataSource = new TestsCollection(10);
 
        summaryItem1 = new GridViewSummaryItem("Id", "Sum of Id: {0}", GridAggregateFunction.Sum);
        var summaryRow1 = new GridViewSummaryRowItem(new[] {summaryItem1});
 
        summaryItem2 = new GridViewSummaryItem("Id2", "Sum of Id2: {0}", GridAggregateFunction.Sum);
        var summaryRow2 = new GridViewSummaryRowItem(new[] { summaryItem2 });
 
        radGridView1.SummaryRowsBottom.Add(summaryRow1);
        radGridView1.SummaryRowsBottom.Add(summaryRow2);
 
        calculatedSummaryItem = new GridViewSummaryItem("Id", null, GridAggregateFunction.Sum);
        var summaryRow3 = new GridViewSummaryRowItem(new[] { calculatedSummaryItem });
 
        radGridView1.SummaryRowsBottom.Add(summaryRow3);
 
        radGridView1.GroupSummaryEvaluate += new GroupSummaryEvaluateEventHandler(radGridView1_GroupSummaryEvaluate);
    }
 
    void radGridView1_GroupSummaryEvaluate(object sender, GroupSummaryEvaluationEventArgs e)
    {
        if (e.SummaryItem == calculatedSummaryItem)
        {
            e.Value = Convert.ToInt32(values[summaryItem2]) - Convert.ToInt32(values[summaryItem1]);
        }
        else
        {
            if (!values.ContainsKey(e.SummaryItem))
            {
                values.Add(e.SummaryItem, e.Value);
            }
            else
            {
                values[e.SummaryItem] = e.Value;
            }
        }
    }
}
 
public class Test
{
    public int Id { get; set; }
    public int Id2 { get; set; }
    public string Name { get; set; }
}
 
public class TestsCollection : BindingList<Test>
{
    public TestsCollection(int noItems)
    {
        for (int i = 0; i < noItems; i++)
        {
            this.Add(new Test { Id = i, Id2 = i + 3, Name = "Test" + i });
        }
    }
}


But the thing you have to take into consideration is that you need to register for the GroupSummaryEvaluate event and on this event you have access to the calculated value. You can either remember the values, like i've stored them in a dictionary based on the summary items and after that just take the necessary values from the dictionary and perform the required operations based on these values.

Hope this helps, if you have any other questions or comments, please let me know,

Best Regards,
Emanuel Varga
Telerik WinForms MVP
0
Zerka
Top achievements
Rank 1
answered on 26 Nov 2010, 04:34 PM
Hi,
Thanks! It really solves the problem by remembering previous values of summaryrows in dictionary and assigning values to new summaryrow in GroupSummaryEvaluate event.

Thank you again. But it would be more convenient if there will be value property of GridViewSummaryItem that can be accessed anywhere in the program.

Regards!
0
Emanuel Varga
Top achievements
Rank 1
answered on 26 Nov 2010, 05:16 PM
Hello again Michael,

I have prepared something more interesting i hope, i will add the entire code at the end of this post but before this i want to explain what i've done here:
First, i've created a custom property and attached it to the grid, in this property we can keep a dictionary of SummaryItems and their corresponding values.
public static class SummaryRowsProperties
{
    public static readonly RadProperty SummaryRowsValues =
        RadProperty.Register("GridViewSummaryItem", typeof(Dictionary<GridViewSummaryItem, object>), typeof(GridTableElement),
        new RadElementPropertyMetadata(new Dictionary<GridViewSummaryItem, object>()));
}
This is the way you can register a new property for one of the grids elements, in this case i have chosen the GridTableElement, because i believe it is the best suited for this case.
We can consider this dictionary as part of the grid, and whenever we will perform a calculation on a summary row we will update the values in this dictionary. So because of this, we can create an extension class for the SummaryItem from which we will be always able to get the latest value from the summary row, like so:
public static class SummaryItemExtensions
{
    public static object GetValue(this GridViewSummaryItem summaryItem, RadGridView grid)
    {
        var dictionary = grid.TableElement.GetValue(SummaryRowsProperties.SummaryRowsValues) as Dictionary<GridViewSummaryItem, object>;
        if (dictionary == null || !dictionary.ContainsKey(summaryItem))
            return null;
 
        return dictionary[summaryItem];
    }
}

The only downside here is that we need to specify the grid also in the GetValue method, or the table element, because the SummaryItem does not have a ParentControl property.

After this we have to handle the most important event here, the GroupSummaryEvaluate event, where we will change / add the values in the dictionary, like so:
void radGridView1_GroupSummaryEvaluate(object sender, GroupSummaryEvaluationEventArgs e)
{
    var dictionary = radGridView1.TableElement.GetValue(SummaryRowsProperties.SummaryRowsValues) as Dictionary<GridViewSummaryItem, object>;
    if (!dictionary.ContainsKey(e.SummaryItem))
    {
        dictionary.Add(e.SummaryItem, e.Value);
    }
 
    if (e.SummaryItem == calculatedSummaryItem)
    {
        var firstSummaryItemValue = dictionary[radGridView1.SummaryRowsBottom[0][0]];
        var secondSummaryItemValue = dictionary[radGridView1.SummaryRowsBottom[1][0]];
        e.Value = Convert.ToInt32(secondSummaryItemValue) - Convert.ToInt32(firstSummaryItemValue);
 
        // or
        e.Value = Convert.ToInt32(radGridView1.SummaryRowsBottom[1][0].GetValue(this.radGridView1)) -  Convert.ToInt32(radGridView1.SummaryRowsBottom[0][0].GetValue(this.radGridView1));
    }
 
    dictionary[e.SummaryItem] = e.Value;
}

I hope everything is clear in the first part of the method, where we add the new items to the dictionary with the corresponding values.
After that, we can get the values for the summary rows in two different way, the first one we need to get the dictionary property from the table element, and based on the SummaryItem we can get the value, or the other one I've proposed here, by using an extension method and just selecting the Item Required and calling a GetValue(RadGridView) on the summary item and if a value has already been calculated for that SummaryItem that value will be returned.
This you can use everywhere in your application.

I hope you understood the basics of this, and as promised i will attach a full example next:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Telerik.WinControls;
using Telerik.WinControls.UI;
 
public partial class Form1 : Form
{
    private RadGridView radGridView1;
    private GridViewSummaryItem calculatedSummaryItem;
 
        public Form1()
    {
        this.Size = new Size(800, 600);
        InitializeComponent();
        this.Controls.Add(radGridView1 = new RadGridView());
        radGridView1.Dock = DockStyle.Fill;
        radGridView1.AutoSizeColumnsMode
            = GridViewAutoSizeColumnsMode.Fill;
 
        radGridView1.DataSource = new TestsCollection(10);
 
        var summaryItem1 = new GridViewSummaryItem("Id", "Sum of Id: {0}", GridAggregateFunction.Sum);
        var summaryRow1 = new GridViewSummaryRowItem(new[] {summaryItem1});
 
        var summaryItem2 = new GridViewSummaryItem("Id2", "Sum of Id2: {0}", GridAggregateFunction.Sum);
        var summaryRow2 = new GridViewSummaryRowItem(new[] { summaryItem2 });
 
        radGridView1.SummaryRowsBottom.Add(summaryRow1);
        radGridView1.SummaryRowsBottom.Add(summaryRow2);
 
        calculatedSummaryItem = new GridViewSummaryItem("Id", null, GridAggregateFunction.Sum);
        var summaryRow3 = new GridViewSummaryRowItem(new[] { calculatedSummaryItem });
 
        radGridView1.SummaryRowsBottom.Add(summaryRow3);
        radGridView1.GroupSummaryEvaluate += new GroupSummaryEvaluateEventHandler(radGridView1_GroupSummaryEvaluate);
    }
 
    void radGridView1_GroupSummaryEvaluate(object sender, GroupSummaryEvaluationEventArgs e)
    {
        var dictionary = radGridView1.TableElement.GetValue(SummaryRowsProperties.SummaryRowsValues) as Dictionary<GridViewSummaryItem, object>;
        if (!dictionary.ContainsKey(e.SummaryItem))
        {
            dictionary.Add(e.SummaryItem, e.Value);
        }
 
        if (e.SummaryItem == calculatedSummaryItem)
        {
            var firstSummaryItemValue = dictionary[radGridView1.SummaryRowsBottom[0][0]];
            var secondSummaryItemValue = dictionary[radGridView1.SummaryRowsBottom[1][0]];
            e.Value = Convert.ToInt32(secondSummaryItemValue) - Convert.ToInt32(firstSummaryItemValue);
 
            // or
            e.Value = Convert.ToInt32(radGridView1.SummaryRowsBottom[1][0].GetValue(this.radGridView1)) -  Convert.ToInt32(radGridView1.SummaryRowsBottom[0][0].GetValue(this.radGridView1));
        }
 
        dictionary[e.SummaryItem] = e.Value;
    }
}
 
public static class SummaryRowsProperties
{
    public static readonly RadProperty SummaryRowsValues =
        RadProperty.Register("GridViewSummaryItem", typeof(Dictionary<GridViewSummaryItem, object>), typeof(GridTableElement),
        new RadElementPropertyMetadata(new Dictionary<GridViewSummaryItem, object>()));
}
 
public static class SummaryItemExtensions
{
    public static object GetValue(this GridViewSummaryItem summaryItem, RadGridView grid)
    {
        var dictionary = grid.TableElement.GetValue(SummaryRowsProperties.SummaryRowsValues) as Dictionary<GridViewSummaryItem, object>;
        if (dictionary == null || !dictionary.ContainsKey(summaryItem))
            return null;
 
        return dictionary[summaryItem];
    }
}
 
public class Test
{
    public int Id { get; set; }
 
    public int Id2 { get; set; }
 
    public string Name { get; set; }
}
 
public class TestsCollection : BindingList<Test>
{
    public TestsCollection(int noItems)
    {
        for (int i = 0; i < noItems; i++)
        {
            this.Add(new Test { Id = i, Id2 = i + 3, Name = "Test" + i });
        }
    }
}

Hope this helps, if you have any other questions or comments, please let me know,

Best Regards,
Emanuel Varga
Telerik WinForms MVP
0
Emanuel Varga
Top achievements
Rank 1
answered on 26 Nov 2010, 05:22 PM
Or maybe even more clean, by not storing the last summaryItem, using Linq and checking if it is the last summary row, something like this:
void radGridView1_GroupSummaryEvaluate(object sender, GroupSummaryEvaluationEventArgs e)
{
    var dictionary = radGridView1.TableElement.GetValue(SummaryRowsProperties.SummaryRowsValues) as Dictionary<GridViewSummaryItem, object>;
    if (!dictionary.ContainsKey(e.SummaryItem))
    {
        dictionary.Add(e.SummaryItem, e.Value);
    }
 
    if (e.SummaryItem == radGridView1.SummaryRowsBottom.LastOrDefault()[0])
    {
        var firstSummaryItemValue = dictionary[radGridView1.SummaryRowsBottom[0][0]];
        var secondSummaryItemValue = dictionary[radGridView1.SummaryRowsBottom[1][0]];
        e.Value = Convert.ToInt32(secondSummaryItemValue) - Convert.ToInt32(firstSummaryItemValue);
 
        // or
        e.Value = Convert.ToInt32(radGridView1.SummaryRowsBottom[1][0].GetValue(this.radGridView1)) - Convert.ToInt32(radGridView1.SummaryRowsBottom[0][0].GetValue(this.radGridView1));
    }
 
    dictionary[e.SummaryItem] = e.Value;
}

Hope this helps, if you have any other questions or comments, please let me know,

Best Regards,
Emanuel Varga
Telerik WinForms MVP
Tags
GridView
Asked by
Zerka
Top achievements
Rank 1
Answers by
Emanuel Varga
Top achievements
Rank 1
Zerka
Top achievements
Rank 1
Share this question
or