Sum function does not work if type implements ICustomTypeDescriptor

1 posts, 0 answers
  1. Petr
    Petr avatar
    1 posts
    Member since:
    Sep 2012

    Posted 11 Mar 2013 Link to this post

    Aggregation functions (Sum, Min, Max) do not work if type implements ICustomTypeDescriptor.
    Same scenario with RadGridView works fine.
    ICustomTypeDescriptor implementation.
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
     
    namespace HOME.Samples.TypeDescriber.Objects
    {
        public class TestResultRowWrapper : Dictionary<string, double?>, ICustomTypeDescriptor
        {
            AttributeCollection ICustomTypeDescriptor.GetAttributes()
            {
                return new AttributeCollection(null);
            }
     
            string ICustomTypeDescriptor.GetClassName()
            {
                return null;
            }
     
            string ICustomTypeDescriptor.GetComponentName()
            {
                return null;
            }
     
            TypeConverter ICustomTypeDescriptor.GetConverter()
            {
                return null;
            }
     
            EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
            {
                return null;
            }
     
            PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
            {
                return null;
            }
     
            object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
            {
                return null;
            }
     
            EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
            {
                return new EventDescriptorCollection(null);
            }
     
            EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
            {
                return new EventDescriptorCollection(null);
            }
     
            PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
            {
                var properties = Keys.Select(key => new TestResultPropertyDescriptor(key)).Cast<PropertyDescriptor>().ToList();
                return new PropertyDescriptorCollection(properties.ToArray());
            }
     
            PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
            {
                return ((ICustomTypeDescriptor)this).GetProperties(null);
            }
     
            object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
            {
                return this;
            }
        }
    }
    TestResultPropertyDescriptor
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
     
    namespace HOME.Samples.TypeDescriber.Objects
    {
        public class TestResultPropertyDescriptor : PropertyDescriptor
        {
            public TestResultPropertyDescriptor(string key)
                : base(key, null)
            {
            }
     
            public override Type ComponentType
            {
                get { return typeof (Dictionary<string, double?>); }
            }
     
            public override bool IsReadOnly
            {
                get { return false; }
            }
     
            public override Type PropertyType
            {
                get { return typeof (double?); }
            }
     
            public override bool CanResetValue(object component)
            {
                return false;
            }
     
            public override object GetValue(object component)
            {
                return ((Dictionary<string, double?>) component)[base.Name];
            }
     
            public override void ResetValue(object component)
            {
                ((Dictionary<string, double?>) component)[base.Name] = 0;
            }
     
            public override void SetValue(object component, object value)
            {
                ((Dictionary<string, double?>) component)[base.Name] = (double?) value;
            }
     
            public override bool ShouldSerializeValue(object component)
            {
                return false;
            }
        }
    }
    View XAML
    <Window x:Class="HOME.Samples.Client.Wpf.View.MainWindow"
            Title="MainWindow" Height="350" Width="525"
            xmlns:ViewModel1="clr-namespace:HOME.Samples.TypeDescriber.ViewModel;assembly=HOME.Samples.TypeDescriber"
            xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" mc:Ignorable="d"
            d:DataContext="{d:DesignInstance Type=ViewModel1:MainWindowViewModel}">
        <Window.Resources>
            <Style x:Key="amountColumnStyle" TargetType="telerik:GridViewDataColumn">
                <Setter Property="FooterCellStyle">
                    <Setter.Value>
                        <Style TargetType="telerik:GridViewFooterCell">
                            <Setter Property="FontWeight" Value="Bold"/>
                            <Setter Property="Background" Value="LightGray"/>
                        </Style>
                    </Setter.Value>
                </Setter>
                <Setter Property="TextAlignment" Value="Right"/>
                <Setter Property="DataFormatString" Value="#,#;(#,#);0"/>
                <Setter Property="FooterTextAlignment" Value="Right"/>
            </Style>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <telerik:RadToolBar>
                <telerik:RadButton Click="RadButtonClick" Content="Sum"/>
            </telerik:RadToolBar>
            <telerik:RadTreeListView x:Name="grid" Grid.Row="1" AutoGeneratingColumn="RadTreeListViewAutoGeneratingColumn" ItemsSource="{Binding Items, Mode=OneTime}"
                                 EnableColumnVirtualization="False" ShowColumnFooters="True"/>
        </Grid>
    </Window>
    View code
    using System.Windows;
    using HOME.Samples.TypeDescriber.Objects;
    using Telerik.Windows.Controls;
    using Telerik.Windows.Data;
     
    namespace HOME.Samples.Client.Wpf.View
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow
        {
            public MainWindow()
            {
                InitializeComponent();
            }
     
            private void RadTreeListViewAutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e)
            {
                if (!(e.ItemPropertyInfo.Descriptor is TestResultPropertyDescriptor))
                {
                    return;
                }
                e.Column.Style = (Style) FindResource("amountColumnStyle");
                e.Column.AggregateFunctions.Add(new SumFunction
                                                    {
                                                        ResultFormatString = "{0:#,#;(#,#);0}",
                                                    });
                ((GridViewDataColumn) e.Column).DataFormatString = "#,#;(#,#);0";
            }
     
            private void RadButtonClick(object sender, RoutedEventArgs e)
            {
                grid.CalculateAggregates();
            }
        }
    }
    ViewModel
    using System.Collections.Generic;
    using HOME.Samples.TypeDescriber.Objects;
     
    namespace HOME.Samples.TypeDescriber.ViewModel
    {
        public class MainWindowViewModel
        {
            private readonly IEnumerable<TestResultRowWrapper> _items;
     
            public MainWindowViewModel()
            {
                _items = new[]
                             {
                                 new TestResultRowWrapper {{"00:15", 10}, {"00:16", null}, {"00:17", 0}},
                                 new TestResultRowWrapper {{"00:15", 3}, {"00:16", 9}, {"00:17", null}}
                             };
            }
     
            public IEnumerable<TestResultRowWrapper> Items
            {
                get { return _items; }
            }
        }
    }
    This behavior occurs only when AutoGenerateColumns is True.
Back to Top