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

My own AggregateFunction

1 Answer 151 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Andy
Top achievements
Rank 1
Andy asked on 28 Nov 2008, 03:13 PM
Hello!

I have a table with time of call in seconds.
I grouping my table and add a SumFunction.
All works great!

But I need display result of SumFunction like this: HH:MM:SS where HH - hours, MM - minutes and SS - seconds.

Can you tell me how to do it?

I can create inheritance class from SumFunction like this:
public class mF : Telerik.Windows.Data.SumFunction  
    {  
        public mF()  
        {  
        }  
 
        public mF(string propertyName, string calculationField, string caption)  
        {  
            base.Name = propertyName;  
            base.SourceField = calculationField;  
            base.Caption = caption;  
        }  
 
        private String GetTime(Decimal totalSeconds)  
        {  
            Int32 hours = (Int32)Math.Floor((double)totalSeconds / (double)3600);  
            Int32 minutes = (Int32)Math.Floor((double)(totalSeconds - (hours * 3600)) / (double)60);  
            Int32 seconds = (Int32)totalSeconds - (hours * 3600) - (minutes * 60);  
 
            return hours.ToString() + ":" + minutes.ToString() + ":" + seconds.ToString();  
        }  
 
        public override Telerik.Windows.Data.AggregateResult Calculate(Telerik.Windows.Data.GroupRecord targetGroup)  
        {  
            Telerik.Windows.Data.AggregateResult result = base.Calculate(targetGroup);  
            result.Value = GetTime(Convert.ToDecimal(result.Value, System.Globalization.CultureInfo.CurrentCulture));  
            return result;  
        }  
    } 
But this class properly work only if I have 1 grouping. 
If I add another one grouping i have exception (what it was necessary to expect, because format HH:MM:SS SumFunction cant convert to Decimal).

Please, help.

1 Answer, 1 is accepted

Sort by
0
Hristo Deshev
Telerik team
answered on 01 Dec 2008, 11:41 AM
Hi Andy,

Aggregate functions require that you return the same data type at all stages of aggregate calculations. That is why when grouping with more than one level, the second-level grouping crashes -- it gets fed the strings returned by the first-level calculations instead of decimals.

I have a better idea on doing custom formatting for aggregate results -- retemplate the GridViewAggregateResultCell control and use a value converter to convert the total seconds into a HH:MM:SS string. Here is the style I used:

<Style TargetType="telerik:GridViewAggregateResultCell"
    <Setter Property="Template"
        <Setter.Value> 
            <ControlTemplate TargetType="telerik:GridViewAggregateResultCell"
                <ControlTemplate.Resources> 
                    <CustomAggregateFunction:SecondsConverter x:Key="secondsConverter" /> 
                </ControlTemplate.Resources> 
                <Border MaxWidth="200" Height="Auto" BorderThickness="1,1,1,1"
                    <Border MinWidth="100" Height="Auto" Background="#00FFFFFF" BorderThickness="1,1,1,1"
                        <StackPanel Orientation="Horizontal"
                            <TextBlock Margin="5,-2,5,0" Foreground="#FF027BA8" Text="{Binding Caption}" /> 
                            <TextBlock Margin="5,-2,5,0" Foreground="#FF027BA8"  
                                       Text="{Binding Value, Converter={StaticResource secondsConverter}}" /> 
                        </StackPanel> 
                    </Border> 
                </Border> 
            </ControlTemplate> 
        </Setter.Value>                  
    </Setter> 
</Style> 

And the SecondsConverter code:

public class SecondsConverter : IValueConverter 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
        decimal seconds = System.Convert.ToDecimal(value, culture); 
        return GetTime(seconds); 
    } 
 
    private String GetTime(Decimal totalSeconds) 
    { 
        Int32 hours = (Int32) Math.Floor((double) totalSeconds / (double) 3600); 
        Int32 minutes = (Int32) Math.Floor((double) (totalSeconds - (hours * 3600)) / (double) 60); 
        Int32 seconds = (Int32) totalSeconds - (hours * 3600) - (minutes * 60); 
 
        //return hours + ":" + minutes + ":" + seconds; 
         
        //explicitly display single-digit numbers such as 6 minutes as 06 minutes 
        return string.Format("{0:00}:{1:00}:{2:00}", hours, minutes, seconds); 
    } 
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
        throw new System.NotImplementedException(); 
    } 

I am attaching my test project for your reference.

Kind regards,
Hristo Deshev
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Tags
GridView
Asked by
Andy
Top achievements
Rank 1
Answers by
Hristo Deshev
Telerik team
Share this question
or