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

problem with custom sort function resetting ItemsSource

1 Answer 80 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Brian Graves
Top achievements
Rank 1
Brian Graves asked on 27 May 2010, 01:54 AM
I have the following scenario.  I want to be able to custom sort (by number) a column contains the following:
Value 0-2
Value 2-4
Value 4-6
Value 6-8
Value 8-10
Value 10+

I looked at the following article:
http://www.telerik.com/help/silverlight/gridview-sorting-custom.html

It requires that I reset the ItemsSource.  To do this, I have a custom function (passing ItemsSource, SortPropertyName, and NewSortingState) which grabs the first number it can find inside the property value and sorts accordingly.  It took me a long time to write a custom function that would sort either regular strings or string with numbers in it (like the ones shown above) so I am sharing it with anyone having a similar scenario.  To do this in my custom sorting function, my ItemsSource is set with the value returned from this function:

 

        private object PerformCustomStringSort(List<object> ItemsSource, string columnName, SortingState sortState)
        {
            PropertyInfo colNameProp = ItemsSource.First().GetType().GetProperty(columnName);

            if (colNameProp == null)
                return 0;

            var sorted = from i in ItemsSource select i;
            MyComparer comparer = new MyComparer();
            if (sortState == SortingState.Ascending)
                sorted = sorted.OrderBy(item => NumericHelper.ObtainNumber(colNameProp.GetValue(item, null)), comparer);
            else
                sorted = sorted.OrderByDescending(item => NumericHelper.ObtainNumber(colNameProp.GetValue(item, null)), comparer);
            return sorted.ToList();
        }

Here are the other classes that are used to accomplish this:

    public static class NumericHelper
    {
        public static bool IsNumeric(object expression)
        {
            if (expression == null)
                return false;

            double testDouble;
            if (double.TryParse(expression.ToString(), out testDouble))
                return true;

            bool testBool;
            if (bool.TryParse(expression.ToString(), out testBool))
                return true;

            return false;
        }

        public static object ObtainNumber(object objValue)
        {
            char[] arEntireString = Convert.ToString(objValue).ToCharArray();
            int iStart = -1;
            int iLength = 0;
            int i = 0;

            for (i = 0; i < arEntireString.Length; i++)
            {
                if (NumericHelper.IsNumeric(arEntireString[i]))
                {
                    if (iStart == -1)
                    {
                        if (i > 0 && arEntireString[i - 1] == '-')
                        {
                            iStart = i - 1;
                            iLength += 1;
                        }
                        else
                        {
                            iStart = i;
                        }
                    }
                    iLength += 1;
                }
                else
                {
                    if (iStart > -1)
                    {
                        if (arEntireString[i] == '.') //decimal
                        {
                            iLength += 1;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            if (iStart > -1 && iLength > 0)
            {
                return (Convert.ToDecimal(Convert.ToString(objValue).Substring(iStart, iLength)));
            }
            else
            {
                return objValue;
            }
        }

    }

    public class MyComparer : IComparer<Object>
    {

        public int Compare(Object valueA, Object valueB)
        {
            if (NumericHelper.IsNumeric(valueA) && NumericHelper.IsNumeric(valueB))
                return int.Parse(Convert.ToString(valueA)).CompareTo(int.Parse(Convert.ToString(valueB)));
            else
                return String.Compare(Convert.ToString(valueA), Convert.ToString(valueB));
        }

    }

 

1 Answer, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 28 May 2010, 10:50 AM
Hi Brian Graves,

Thank you a lot for sharing this great and useful example. Please, keep up in the same spirit. 
I have updated your Telerik points.

All the best,
Maya
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.
Tags
GridView
Asked by
Brian Graves
Top achievements
Rank 1
Answers by
Maya
Telerik team
Share this question
or