
Albert Shenker
Top achievements
Rank 1
Veteran
Iron
Albert Shenker
asked on 15 Oct 2008, 06:33 AM
I have a grid which uses grouping. I would like to implement some functionality that calculates some group-level stats on some of the columns in the grid, however I need to use TemplateColumns, so the built-in aggregates won't work. I am able to do the calculation in the grid's ItemDataBound event, however, at this point in the grid cycle, I don't have access to know which group i am in so the calculations won't be made on a group-level, as I want. Does anyone know how to accomplish this? A simple example would be a grid with a Template column which shows an Integer (the template column is needed for a variety of treasons which aren't pertinent). I would like the group header (or footer) to show a calculation made on this column (such as the number of items in the group which are greater than some fixed value)
18 Answers, 1 is accepted
0

Shinu
Top achievements
Rank 2
answered on 15 Oct 2008, 11:28 AM
Hi Albert,
Try the following approach and see if it is helpful.
ASPX:
CS:
Thanks
Shinu.
Try the following approach and see if it is helpful.
ASPX:
<telerik:GridTemplateColumn DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" UniqueName="SupplierID" DataType="System.Int32" > |
<ItemTemplate> |
<asp:Label ID="Label1" runat="server" Text='<%#Eval("SupplierID") %>'></asp:Label> |
</ItemTemplate> |
</telerik:GridTemplateColumn> |
CS:
protected void RadGrid1_PreRender(object sender, EventArgs e) |
{ |
foreach (GridGroupHeaderItem groupHeader in RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader)) |
{ |
GridItem[] children = groupHeader.GetChildItems(); |
foreach (GridDataItem child in children) |
{ |
GridDataItem childchildItem = child as GridDataItem; |
Label lbl = (Label)childItem["SupplierID"].FindControl("Label1"); |
total += Double.Parse(lbl.Text); |
} |
Label lbl1 = new Label(); |
lbl1.ID = "Label2"; |
lbl1.Text = string.Empty; |
lbl1.Text = total.ToString(); ; |
groupHeader.DataCell.Controls.Add(lbl1); |
} |
} |
Thanks
Shinu.
0

Albert Shenker
Top achievements
Rank 1
Veteran
Iron
answered on 16 Oct 2008, 10:46 AM
Thanks for the suggestion, however, in my real application, I will not be able to perform the aggregate calculation by simply reading the column text. The function is far too complicated, so I need to have access to the actual underlying dataitem. I have access to this in the Itemdatabound event, however, I don;t seem to have access to the necessary GroupIndex here. In the prerender event, I have access to the group index, but not the uderlying data which i need.
0

Albert Shenker
Top achievements
Rank 1
Veteran
Iron
answered on 16 Oct 2008, 04:02 PM
I think I figured out how to do this. I am able to get access to the underlying data at pre-render by accessing the GridGroupHeaderItem children, and then casting to my custom object. Furthermore, I can parse the GroupIndex property in order to loop through and set the proper headers for the hierarchical groups. Thanks for the lead!
0

Priya
Top achievements
Rank 1
answered on 31 Dec 2008, 11:13 PM
I have seen the above code for adding a control in the GridGroupHeaderItem. But How do I add a control into a GroupFooterItem?
I have a grid that uses grouping and I need to display the aggregate of a template column in the footer.
I have a grid that uses grouping and I need to display the aggregate of a template column in the footer.
0

Shinu
Top achievements
Rank 2
answered on 02 Jan 2009, 06:58 AM
Hi Priya,
You can add control to the GridGroupFooter as shown below.
CS:
Thanks
Shinu
You can add control to the GridGroupFooter as shown below.
CS:
foreach(GridGroupFooterItem footer in RadGrid1.MasterTableView.GetItems(GridItemType.GroupFooter) ) |
{ |
Label lbl =new Label(); |
lbl.ID="Label1"; |
lbl.Text="CustomText"; |
footer.Cells[3].Controls.Add(lbl); |
} |
Thanks
Shinu
0

Priya
Top achievements
Rank 1
answered on 02 Jan 2009, 01:44 PM
Cells[3] was what I was missing. Thank you. It worked!
0

Mike
Top achievements
Rank 1
answered on 15 Feb 2010, 04:29 PM
I am trying this approach using the prerender and adding this to the radGrid
But I am getting the following error, your help would be greatly appreciated..
Compiler Error Message: CS0103: The name 'childItem' does not exist in the current context
Source Error:
OnPreRender="RadGrid1_PreRender" |
<telerik:GridTemplateColumn HeaderText="Avg" ItemStyle-HorizontalAlign="Center" UniqueName="AvgPrice"> |
<ItemTemplate> |
<asp:Label ID="LabelAvgPrice" runat="server" /> |
</ItemTemplate> |
</telerik:GridTemplateColumn> |
protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e) |
{ |
if (e.Item is GridDataItem) |
{ |
Label avgPrice = (Label)e.Item.Cells[0].FindControl("LabelAvgPrice"); |
avgPrice.Text = Convert.ToString(CalculateThis(value1,value2)); |
} |
} |
But I am getting the following error, your help would be greatly appreciated..
Compiler Error Message: CS0103: The name 'childItem' does not exist in the current context
Source Error:
|
0

Albert Shenker
Top achievements
Rank 1
Veteran
Iron
answered on 15 Feb 2010, 04:40 PM
The error message is pointing you to your problem (line 178). It doesn't appear that you have defined childItem. It looks like you defined childchildItem.
0

Mike
Top achievements
Rank 1
answered on 15 Feb 2010, 04:43 PM
Thank you for the quick response, how do I define the childitem? I am grouping this grid on four columns.
0

Albert Shenker
Top achievements
Rank 1
Veteran
Iron
answered on 15 Feb 2010, 05:00 PM
Here's an example in VB. You'll need to get Telerik Support if you can't translate this into C#, but I believe a close example is below in the Oct 15, 2008 post from Telerik. I have noticed that the Telerik Posts contain what appear to be some syntax errors, perhaps caused by the message board pasting mechanism. This seemed to cause the childchildItem issue. Anyhow, if you change childchildItem in their example to just childItem, it might work, but I am unfamiliar with the C# syntax on that line, so you will need to check with them.
you will notice in the original post here, that the Telerik agen uses C#, and also there appears to be sme syntax issue with their code (the appearance of childchildItem). I think if you changed this to just
Private Sub MyGrid_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyGrid.PreRender |
For Each grpHeaderItem As GridGroupHeaderItem In MyGrid.MasterTableView.GetItems(GridItemType.GroupHeader) |
Dim index As Integer = grpHeaderItem.GroupIndex |
For Each childItem As GridItem In grpHeaderItem.GetChildItems() |
If TypeOf (childItem) Is GridDataItem Then |
Dim obj As MyCustomObject = DirectCast(childItem.DataItem, MyCustomObject) |
' Now I have a reference to the underlying data object, as well as the group index |
End If |
Next |
Next |
End Sub |
you will notice in the original post here, that the Telerik agen uses C#, and also there appears to be sme syntax issue with their code (the appearance of childchildItem). I think if you changed this to just
0

Mike
Top achievements
Rank 1
answered on 15 Feb 2010, 05:10 PM
I am using this
I used your converter to generate this from your code and it throws the following error.
Compiler Error Message: CS0029: Cannot implicitly convert type 'string' to 'int'
Source Error:
protected void RadGrid1_PreRender(object sender, EventArgs e) |
{ |
foreach (GridGroupHeaderItem groupHeader in RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader)) |
{ |
GridItem[] children = groupHeader.GetChildItems(); |
foreach (GridDataItem child in children) |
{ |
GridDataItem childchildchildItem = child as GridDataItem; |
Label lbl = (Label)childItem["AvgPrice"].FindControl("LabelAvgPrice"); |
total += Double.Parse(lbl.Text); |
} |
Label lbl = new Label(); |
lbl.ID = "LabelAvgPrice"; |
lbl.Text = "CustomText"; |
footer.Cells[12].Controls.Add(lbl); |
} |
} |
I used your converter to generate this from your code and it throws the following error.
Compiler Error Message: CS0029: Cannot implicitly convert type 'string' to 'int'
Source Error:
|
private void RadGrid1_PreRender(object sender, System.EventArgs e) |
{ |
foreach (GridGroupHeaderItem grpHeaderItem in RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader)) |
{ |
int index = grpHeaderItem.GroupIndex; |
foreach (GridItem childItem in grpHeaderItem.GetChildItems()) |
{ |
if ((childItem) is GridDataItem) |
{ |
MyCustomObject obj = (MyCustomObject)childItem.DataItem; |
// Now I have a reference to the underlying data object, as well as the group index |
} |
} |
} |
} |
0

Albert Shenker
Top achievements
Rank 1
Veteran
Iron
answered on 15 Feb 2010, 05:21 PM
Again, there appears to be some issue in the message board C# code pasting functionality. It keeps appending "child" to the variable name, which isn't right.
0

Mike
Top achievements
Rank 1
answered on 15 Feb 2010, 05:23 PM
I see that and have update it and it blows up on "total' now, where is that defined?
Compiler Error Message: CS0103: The name 'total' does not exist in the current context
Source Error:
protected void RadGrid1_PreRender(object sender, EventArgs e) |
{ |
foreach (GridGroupHeaderItem groupHeader in RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader)) |
{ |
GridItem[] children = groupHeader.GetChildItems(); |
foreach (GridDataItem child in children) |
{ |
GridDataItem childItem = child as GridDataItem; |
Label lbl = (Label)childItem["AvgPrice"].FindControl("LabelAvgPrice"); |
total += Double.Parse(lbl.Text); |
} |
Label lbl1 = new Label(); |
lbl1.ID = "LabelAvgPrice"; |
lbl1.Text = "0.00"; |
groupHeader.DataCell.Controls.Add(lbl1); |
} |
} |
Compiler Error Message: CS0103: The name 'total' does not exist in the current context
Source Error:
|
0

Mike
Top achievements
Rank 1
answered on 15 Feb 2010, 05:23 PM
Sorry, double post... but I think we are close.. if we can get this recent error resolved.
0

Albert Shenker
Top achievements
Rank 1
Veteran
Iron
answered on 15 Feb 2010, 05:29 PM
The variable total is never defined. You need to define the variable prior to setting its value. Again, I don't write in C#, but I think you can do:
Double total = 0;
prior to the line where you set the value.
Double total = 0;
prior to the line where you set the value.
0

Mike
Top achievements
Rank 1
answered on 15 Feb 2010, 05:34 PM
I appreciate your assitance Albert, the error is gone but I don't see the label in the grouped footer.
0

Albert Shenker
Top achievements
Rank 1
Veteran
Iron
answered on 15 Feb 2010, 05:48 PM
I believe the examples here will add the label to the group header, not the group footer. I see in one of your examples you use the varialbe "footer", but i'm not sure what that refers to.
If you can't get it to work, I would suggest you submit a formal support ticket to Telerik.
If you can't get it to work, I would suggest you submit a formal support ticket to Telerik.
0

Phil H.
Top achievements
Rank 2
answered on 10 Sep 2014, 02:17 PM
Hi All:
I downloaded the 'sample' code. This is my version of the Calculate function (hope it helps):
Phil
I downloaded the 'sample' code. This is my version of the Calculate function (hope it helps):
//
/// <
summary
>
/// Calculate the custom aggregate function
/// </
summary
>
/// <
param
name
=
"grid"
>the RadGrid</
param
>
/// <
param
name
=
"group"
>current group of row items to apply the aggregate function</
param
>
/// <
returns
>weighted average price</
returns
>
protected decimal CalculateWeightedAverage(RadGrid grid, GridGroupHeaderItem @group)
{
try {
int _weightCol = grid.MasterTableView.GetColumn("ContractedLbs").OrderIndex;
int _priceCol = grid.MasterTableView.GetColumn("ContractedPrice").OrderIndex;
decimal _groupWeightedPrice = 0m;
int _groupTotalWeight = 0;
foreach (GridItem _item in @group.GetChildItems()) {
if (_item is GridDataItem) {
string _weightStr = _item.Cells(_weightCol).Text;
string _priceStr = _item.Cells(_priceCol).Text;
_groupWeightedPrice += Convert.ToDecimal(_priceStr) * Convert.ToInt32(_weightStr);
_groupTotalWeight += Convert.ToInt32(_weightStr);
}
}
if (_groupTotalWeight != 0) {
return _groupWeightedPrice / _groupTotalWeight;
}
} catch {
}
return 0.0;
}
Phil