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

Sum function does not work if type implements ICustomTypeDescriptor

0 Answers 90 Views
TreeListView
This is a migrated thread and some comments may be shown as answers.
Petr
Top achievements
Rank 1
Petr asked on 11 Mar 2013, 10:08 AM
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.

No answers yet. Maybe you can help?

Tags
TreeListView
Asked by
Petr
Top achievements
Rank 1
Share this question
or