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

[Solved] Aggregates bug

5 Answers 178 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Zack
Top achievements
Rank 1
Zack asked on 25 Feb 2010, 06:53 PM
Hi,

I am on internal build 2009_3_1423.

I have a context menu within a button in my numeric column headers.  This allows the user to select, Sum, Average, Min, Max etc.  When they do this I add the relevant aggregate to the relevant column.  Once added I call grid.CalculateAggregates() - this works fine with one column.  However, when you bring two or columns into the mix things turn ugly.  If I add aggregates to the secound column, they are added to the first column as well, and the values of all aggregates change to the values of the column that has just been acted on.

Any ideas on how to fix this would be great.

Thanks

Zack


Code is below

//Class

using Telerik.Windows.Data;
using Telerik.Windows.Controls;
using System.Linq;
using System;

namespace Infrastructure.Factory
{
    public class AggregationFactory
    {
        public static void SetSubTotalForColumn(RadGridView grid, RadMenuItem item, string uniqueColumnNameAndSourceField)
        {
            if (!grid.ShowColumnFooters)
                grid.ShowColumnFooters = true;

            if (!item.IsChecked)
            {
                AggregationFactory.AddAggregationToGrid(
                    grid,
                    AggregationFactory.GetAggregation(Convert.ToString(item.Header), uniqueColumnNameAndSourceField),
                    uniqueColumnNameAndSourceField);
                item.IsChecked = true;
            }
            else
            {
                AggregationFactory.RemoveAggregationFromGrid(
                    grid,
                    Convert.ToString(item.Header),
                    uniqueColumnNameAndSourceField);
                item.IsChecked = false;

                if (grid.AggregateResults.Count == 0)
                    grid.ShowColumnFooters = false;

            }

        }
        private static AggregateFunction GetAggregation(string functionName, string sourceField)
        {
            switch (functionName)
            {
                case "Average":
                    return new AverageFunction(){ Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###.00}", FunctionName = functionName, SourceField = sourceField};
                case "Count":
                    return new CountFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###}", FunctionName = functionName };                   
                case "Max":
                    return new MaxFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###.00}", FunctionName = functionName, SourceField = sourceField };                   
                case "Min":
                    return new MinFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###.00}", FunctionName = functionName, SourceField = sourceField };                   
                case "Sum":
                    return new SumFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###.00}", FunctionName = functionName, SourceField = sourceField };                   
                default:
                    return null;                   
            }
        }
        private static void AddAggregationToGrid(RadGridView grid, AggregateFunction function, string uniqueColumn)
        {
            ((GridViewDataColumn)grid.Columns[uniqueColumn]).AggregateFunctions.Add(function);
            grid.CalculateAggregates();
        }
        private static void RemoveAggregationFromGrid(RadGridView grid, string functionName, string uniqueColumn)
        {
            ((GridViewDataColumn)grid.Columns[uniqueColumn]).AggregateFunctions.Remove(
                ((GridViewDataColumn)grid.Columns[uniqueColumn]).AggregateFunctions.First(func => func.FunctionName == functionName)
                );
            grid.CalculateAggregates();
        }
    }
}

//Event Handler in code behind
private void RadContextMenu_ItemClick(object sender, RadRoutedEventArgs e)
        {
            RadContextMenu menu = (RadContextMenu)sender;           
            RadMenuItem item = (RadMenuItem)e.OriginalSource;
            AggregationFactory.SetSubTotalForColumn(this.GridDataClients, item, Convert.ToString(menu.Tag));          
        }

//XAML for context menu within header

<telerikGridView:GridViewDataColumn DataMemberBinding="{Binding Path=NumericColumn}" IsVisible="True" DataFormatString="{}{0:#,###.00}" TextAlignment="Right" UniqueName="NumericColumn">
                    <telerikGridView:GridViewDataColumn.Header>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width="Auto"  />
                            </Grid.ColumnDefinitions>
                            <StackPanel Orientation="Horizontal" Grid.Column="0" Margin="0,5">
                                <TextBlock Text="Alloc Total Cash" VerticalAlignment="Center" />
                            </StackPanel>
                            <Button Grid.Column="1">
                                <Button.Template>
                                    <ControlTemplate>
                                        <Image Source="Resources/SomeImage.png" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Right" />
                                    </ControlTemplate>
                                </Button.Template>
                                <Navigation:RadContextMenu.ContextMenu>
                                    <Navigation:RadContextMenu telerik:StyleManager.Theme="Windows7" EventName="Click" ItemClick="RadContextMenu_ItemClick" Tag="NumericColumn">
                                        <Navigation:RadContextMenu.Items>
                                            <Navigation:RadMenuItem Header="Average" />
                                            <Navigation:RadMenuItem Header="Count" />
                                            <Navigation:RadMenuItem Header="Max" />
                                            <Navigation:RadMenuItem Header="Min" />
                                            <Navigation:RadMenuItem Header="Sum"/>
                                        </Navigation:RadContextMenu.Items>
                                    </Navigation:RadContextMenu>
                                </Navigation:RadContextMenu.ContextMenu>
                            </Button>
                        </Grid>
                    </telerikGridView:GridViewDataColumn.Header>
                </telerikGridView:GridViewDataColumn>      

5 Answers, 1 is accepted

Sort by
0
Pavel Pavlov
Telerik team
answered on 02 Mar 2010, 04:24 PM
Hi Zack,

I have used  your code within a test project but could not reproduce the problem . Please find the project attached.

Let me know if I can be in assistance further.

Greetings,
Pavel Pavlov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Zack
Top achievements
Rank 1
answered on 02 Mar 2010, 04:46 PM
Hi Pavel,

Thanks for that, when I run your project I get the error.   Please see my screen shot attached.

Once I select a sum on the secound column, the sum value on the first column updates to be the same value.  You can see in the screen shot that the sums in both columns are the same.

Thanks

Zack
0
Pavel Pavlov
Telerik team
answered on 04 Mar 2010, 02:04 PM
Hi Zack,

Please excuse me! My mistake. Indeed I could clearly see the problem after your clarifications. This is being addressed immediately so that the fix will be present in the official release (expected next week) .
Thanks for reporting the bug! I have updated  your Telerik points.

Sincerely yours,
Pavel Pavlov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Pavel Pavlov
Telerik team
answered on 04 Mar 2010, 03:27 PM
Hello Zack,

When trying to fix the problem in RadGridView  I have found that the reason was a bit  different than expected. The good news is that there is no need to wait for the release to get a fix .

In short :

Your AggregationFactory class generates functions with hardcoded names e.g. when adding sum functions - the function name for all functions , for all columns would be "Sum"( taken from the menu header) .

Internally RadGridVIew uses function names to find a matching one to be displayed in the footer cell and the problem comes from duplication of aggregate  function names  - two columns have aggregates with the same function names.

The solution :  I have slightly altered your GetAggregation method so it appends the column name to the function name, thus  avoiding the duplication

Here  is the modified piece of code :
private static AggregateFunction GetAggregation(string functionName, string sourceField)
       {
           switch (functionName)
           {
               case "Average":
                   return new AverageFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###.00}", FunctionName = functionName, SourceField = sourceField };
               case "Count":
                   return new CountFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###}", FunctionName = functionName + sourceField };
               case "Max":
                   return new MaxFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###.00}", FunctionName = functionName + sourceField, SourceField = sourceField };
               case "Min":
                   return new MinFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###.00}", FunctionName = functionName + sourceField, SourceField = sourceField };
               case "Sum":
                   return new SumFunction() { Caption = string.Concat(functionName, " : "), ResultFormatString = "{0:#,###.00}", FunctionName = functionName + sourceField, SourceField = sourceField };
               default:
                   return null;
           }
       }

* You can replace this method and give it a try.  Any other solution making the functionName unique and avoiding name duplication  will also  do the trick .

All the best,
Pavel Pavlov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Zack
Top achievements
Rank 1
answered on 04 Mar 2010, 04:32 PM
That works great!

Thanks very much Pavel.

Zack.
Tags
GridView
Asked by
Zack
Top achievements
Rank 1
Answers by
Pavel Pavlov
Telerik team
Zack
Top achievements
Rank 1
Share this question
or