Sorting items inside a Group

4 posts, 0 answers
  1. Daní
    Daní avatar
    303 posts
    Member since:
    Feb 2008

    Posted 26 Mar 2012 Link to this post

    Hello,

    I have a GridView with grouped by a string property. I want the items inside each grup sorted by a datetime property. Data items looks like:
    public class DataItem
        {
            public string Property1 { get; set; }
     
            public string Property2 { get; set; }
     
            public DateTime Date { get; set; }
        }

    Searching at this forum I found an old thread :http://www.telerik.com/community/forums/silverlight/gridview/how-to-group-and-sort-by-another-column.aspx so I modified the data like follows:
    public class DataItem
        {
            public DataItem(string p1, string p2, DateTime date)
            {
                Property1 = p1;
     
                Property2 = p2;
                Date = date;
                ItemInfo = new DataItemInfo (p1, date);
            }
     
            public string Property1 { get; set; }
     
            public string Property2 { get; set; }
     
            public DateTime Date { get; set; }
     
            public DataItemInfo ItemInfo { get; set; }
        }
     
        public class DataItemInfo: IComparable
        {
            public DataItemInfo(string p1, DateTime date)
            {
                Property1 = p1;
                Date = date;
            }
     
            public string Property1 { get; set; }
     
            public DateTime Date { get; set; }
            #region Implementation of IComparable
     
            /// <summary>
            /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
            /// </summary>
            /// <returns>
            /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj"/>.Greater than zero This instance follows <paramref name="obj"/> in the sort order.
            /// </returns>
            /// <param name="obj">An object to compare with this instance. </param><exception cref="T:System.ArgumentException"><paramref name="obj"/> is not the same type as this instance. </exception>
            public int CompareTo(object obj)
            {
                return Date.CompareTo(((DataItemInfo) obj).Date);
            }
     
            #endregion
     
            public override bool Equals(object obj)
            {
                return Property1.Equals(((DataItemInfo) obj).Property1);
            }
     
            public override int GetHashCode()
            {
                return Property1.GetHashCode();
            }
     
            public static bool operator ==(DataItemInfo a, DataItemInfo b)
            {
                if (ReferenceEquals(a, b))
                    return true;
                if (((object)a == null) || ((object)b == null))
                    return false;
                return a.Property1 == b.Property1;
            }
            public static bool operator !=(DataItemInfo a, DataItemInfo b)
            {
                return !(a == b);
            }
        }

    Xaml looks like:
    <telerik:RadGridView AutoGenerateColumns="False">
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn Header="Property2" DataMemberBinding="{Binding Path=Property2}"/>
                    <telerik:GridViewDataColumn Header="Date" DataMemberBinding="{Binding Path=Date}"/>
                </telerik:RadGridView.Columns>
                <telerik:RadGridView.GroupDescriptors>
                    <data:GroupDescriptor Member="ItemInfo"/>
                </telerik:RadGridView.GroupDescriptors>
            </telerik:RadGridView>

    Using this approch doesn't seem to work, CompareTo method on DataItemInfo class is never invoked. Setting SortDirection="Ascending" in GroupDescription xaml definitiion produces a NullReferencedException: Telerik.Windows.Data!Telerik.Windows.Data.IGroupDescriptorExtensions.GetGroupSortKeyFunction...

    After some more searching in this forum, I decided to create a custom GroupDescriptor by inhereting from GroupDescriptor, code is as follows:

    public class SortingGroupDescriptor : GroupDescriptor
        {
            public AggregateFunction Sorting { get; set; }
            public override Expression CreateGroupSortExpression(Expression groupingExpression)
            {
                var expr = base.CreateGroupSortExpression(groupingExpression);
                expr = Expression.Property(expr, "Date");
                return expr;
            }
        }

    Now, xaml looks like
    <telerik:RadGridView AutoGenerateColumns="False">
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn Header="Property2" DataMemberBinding="{Binding Path=Property2}"/>
                    <telerik:GridViewDataColumn Header="Date" DataMemberBinding="{Binding Path=Date}"/>
                </telerik:RadGridView.Columns>
                <telerik:RadGridView.GroupDescriptors>
                    <local:SortingGroupDescriptor Member="ItemInfo"/>
                </telerik:RadGridView.GroupDescriptors>
            </telerik:RadGridView>

    Again, this approcah doesn't work. Again, setting  SortDirection="Ascending"  produces the same exception as before.

    Any help?

    Thanks
  2. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 26 Mar 2012 Link to this post

    Hello,

     Have you checked this forum thread? This one should be helpful as well.
    Please let me know if you can use a generic GroupDescriptor in your case?

    Greetings,
    Didie
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. DevCraft banner
  4. Daní
    Daní avatar
    303 posts
    Member since:
    Feb 2008

    Posted 26 Mar 2012 Link to this post

    Hello Didie,

    Thanks for your response. Finally I could solve the exception raise produced when I set SortDirection property to the GroupDescriptor in xaml. I needed to provide the member type on the SortingGroupDescriptor implementation. Now Implementation looks like:
    public class DataItem
        {
            public DataItem(string p1, string p2, DateTime date)
            {
                Property1 = p1;
                Property2 = p2;
                Date = date;
                ItemInfo = new DataItemInfo(p1, date);
            }
            public string Property1 { get; set; }
     
            public string Property2 { get; set; }
     
            public DateTime Date { get; set; }
     
            public DataItemInfo ItemInfo { get; set; }
        }
     
        public class DataItemInfo: IEquatable<DataItemInfo>, IComparable<DataItemInfo>
        {
            public DataItemInfo(string p1, DateTime date)
            {
                Property1 = p1;
                Date = date;
            }
     
            public string Property1 { get; set; }
     
            public DateTime Date { get; set; }
     
            #region Implementation of IEquatable<DataItemInfo>
     
            /// <summary>
            /// Indicates whether the current object is equal to another object of the same type.
            /// </summary>
            /// <returns>
            /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
            /// </returns>
            /// <param name="other">An object to compare with this object.</param>
            public bool Equals(DataItemInfo other)
            {
                return other.Property1 == Property1;
            }
     
            #endregion
     
            #region Implementation of IComparable<in DataItemInfo>
     
            /// <summary>
            /// Compares the current object with another object of the same type.
            /// </summary>
            /// <returns>
            /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object is greater than <paramref name="other"/>.
            /// </returns>
            /// <param name="other">An object to compare with this object.</param>
            public int CompareTo(DataItemInfo other)
            {
                return Date.CompareTo(other.Date);
            }
     
            #endregion
        }
     
        public class DataItemInfoGroupDescriptor: GroupDescriptor
        {
            public override Type MemberType
            {
                get { return typeof (DataItemInfo); }
                set
                {
                    base.MemberType = value;
                }
            }
        }

    Xaml is as simple as:


    <telerik:RadGridView AutoGenerateColumns="False">
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn Header="Property2" DataMemberBinding="{Binding Path=Property2}"/>
                    <telerik:GridViewDataColumn Header="Date" DataMemberBinding="{Binding Path=Date}"/>
                </telerik:RadGridView.Columns>
                <telerik:RadGridView.GroupDescriptors>
                    <local:DataItemInfoGroupDescriptor Member="ItemInfo" SortDirection="Ascending"/>
                </telerik:RadGridView.GroupDescriptors>
            </telerik:RadGridView>

    Now, apparently is working fine, I can insert a breakpoint at CompareTo method in DataItemInfo class and execution breaks ath this point. But result is not the desired yet. I think I have missunderstood something. This approach is sorting the grups by Date, it sorts the group based on the lowest Date inside each group. That's not what I want. I want to sort items by date inside each group, so groups should be sorted by Property1 and DataItem's inside each group should be sorted by Date. I've tried to add a SortDescriptor for Date property by, initially, the GridView appears not sorted.
  5. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 27 Mar 2012 Link to this post

    Hi,

    If you want to sort the groups another property, then the group should not have any sorting defined. For example if you take a look at this online demo where a grouping is applied. Initially there is a sorting applied to the Category group. If you cancel this sorting, then you can sort on any of the other columns of the GridView.

    Kind regards,
    Didie
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Back to Top