How to sort numerically on a string field

15 posts, 0 answers
  1. Hector
    Hector avatar
    92 posts
    Member since:
    May 2009

    Posted 12 Jan 2010 Link to this post

    I have a RadGridView bound to a table that has numeric values in a string column.  When I sort, it sorts alphabetic rather than numeric.  For example, say the values are 

    "1000"

     

     

    , "1001", "1002", "159", "17", "13"

    it will sort in this order:

    1000

    1001

    1002

    13

    159

    17


    I tried doing a custom sort, but I am stuck on how to convert the column to int on the fly.  Any help is appreciated.

    Thanks,
  2. Ludovic Gerbault
    Ludovic Gerbault avatar
    226 posts
    Member since:
    Apr 2009

    Posted 12 Jan 2010 Link to this post

    I think you might try to register the autogeneratingcolumn event of the grid, and in the method, something like

    private void OnAutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e) 
          GridViewDataColumn col = e.Column as GridViewDataColumn; 
          //Here you can test the content of your column to determine which DataType you want 
     
          col.DataType = typeof(YourType); 

    Hope this helps


  3. DevCraft banner
  4. Hector
    Hector avatar
    92 posts
    Member since:
    May 2009

    Posted 12 Jan 2010 Link to this post

    Good idea, but it didn't work.  I am not automatically generating the columns, I am creating them programatically and I tried setting the column to dataColumn.DataType = typeof(int); and it will still sort alphabetically.  Thanks for trying.
  5. Pavel Pavlov
    Admin
    Pavel Pavlov avatar
    2039 posts

    Posted 12 Jan 2010 Link to this post

    Hello Hector,

    For such scenarios RadGridView exposes the Sorting event.

    It allows you to perform a custom sorting logic when the user clicks on the column header.
    You may see this event in action in this online example.

    This event allows you to 'override' the default sorting logic.So for your scenario you will need to subscribe to the Sorting event and perform  your own sorting within the event handler.

    Pavel Pavlov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  6. Hector
    Hector avatar
    92 posts
    Member since:
    May 2009

    Posted 12 Jan 2010 Link to this post

    Thanks Pavel.  I am handling it that way.  I just don't know how to apply the sort to the values in numeric style.
    I tried doing

    values = values.OrderByDescending(v =>

    int.Parse(v.Value));

     

    and it wouldn't work.


    Here is the code I have now:
    private void CustomSortingGrid_Sorting(object sender, GridViewSortingEventArgs e)  
            {  
                //Gets the value of the ItemsSource property as IEnumerable.  
                IEnumerable<ValidValue> values = e.DataControl.ItemsSource as IEnumerable<ValidValue>;  
                //Checks if the value of the collection is null.  
     
                if (values == null)  
                {  
                    e.Cancel = true;  
                    return;  
                }  
                //If the sorting state is none, sort the items ascending.  
                if (e.OldSortingState == SortingState.None)  
                {  
                    e.NewSortingState = SortingState.Ascending;  
                    values = values.OrderBy(v => v.GetType()   
                        .GetProperty(e.SortPropertyName)   
                        .GetValue(v, null));  
                      
                }  
                //If the sorting state is ascending, sort the items descending.  
                else if (e.OldSortingState == SortingState.Ascending)  
                {  
                    e.NewSortingState = SortingState.Descending;  
                    values = values.OrderByDescending(v => v.GetType()  
                        .GetProperty(e.SortPropertyName)  
                        .GetValue(v, null));  
                      
                }  
                //If the sorting state is descending, apply default sorting to the items.  
                else 
                {  
                    e.NewSortingState = SortingState.None;  
                    values = values.OrderBy(v => v.ValueID);  
                }  
                //Set the sorted collection as source of the RadGridView  
                e.DataControl.ItemsSource = values.ToList();  
                e.Cancel = true;  
            } 
  7. Pavel Pavlov
    Admin
    Pavel Pavlov avatar
    2039 posts

    Posted 15 Jan 2010 Link to this post

    Hello Hector,

    Here is some code I have tested and seems to work ok . ( For simplicity it contains just the sorting logic  to sort ascending once , without cycling the sort states)

    public partial class MainPage : UserControl
       {
           public MainPage()
           {
               InitializeComponent();
               List<Item> items = new List<Item>();
               for (int i = 30; i >0; i--)
               {
                   items.Add(new Item() { Value = i.ToString() });
               }
               this.RadGridView1.ItemsSource = items;
               this.RadGridView1.Sorting += new EventHandler<Telerik.Windows.Controls.GridViewSortingEventArgs>(RadGridView1_Sorting);
           }
           void RadGridView1_Sorting(object sender, Telerik.Windows.Controls.GridViewSortingEventArgs e)
           {
               e.Cancel = true;//cancel the built in sorting so we can perform our custom logic instead
               this.PerformCustomStringSort();
           }
           private void PerformCustomStringSort()
           {
               var sorted = from i in this.RadGridView1.ItemsSource as List<Item>
                            orderby int.Parse( i.Value) ascending
                            select i;
               this.RadGridView1.ItemsSource = sorted.ToList();
           }
       }
       public class Item
       {
           public string Value { get; set; }
       }

    All the best,
    Pavel Pavlov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  8. Hector
    Hector avatar
    92 posts
    Member since:
    May 2009

    Posted 18 Jan 2010 Link to this post

    Thanks for your reply, but it did not work.  Here is the error I am getting:
    Value cannot be null.
    Parameter name: source
    I get this error at the linq line
    var sorted = from i in this.gridMultiSelect.ItemsSource as List<ValidValue>  
                             orderby int.Parse(i.Value) ascending  
                             select i; 

    Any other ideas?
  9. Pavel Pavlov
    Admin
    Pavel Pavlov avatar
    2039 posts

    Posted 19 Jan 2010 Link to this post

    Hi Hector,

    I have tested the code and it seems OK . However your exception gives me a hint that you may have null values in your data.

    If that is the case here is how you can extend the  linq query to handle and sort null values as well without giving exception.

    private void PerformCustomStringSort()
          {
              var sorted = from i in this.RadGridView1.ItemsSource as List<Item>
                           orderby  i.Value==null?0:int.Parse(i.Value) ascending
                           select i;
              this.RadGridView1.ItemsSource = sorted.ToList();
          }

    Let me know if you need a working project using this code as a sample.

    Sincerely yours,
    Pavel Pavlov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  10. Hector
    Hector avatar
    92 posts
    Member since:
    May 2009

    Posted 19 Jan 2010 Link to this post

    Thanks again, Pavel, but I am still getting the error "value cannot be null. parameter name: source"
    The error occurs even if I don't do the orderby.
    var sorted = from i in this.RadGridView1.ItemsSource as List<Item>   
       
                           select i;   
     
    So I think something else in my data is null.
  11. Pavel Pavlov
    Admin
    Pavel Pavlov avatar
    2039 posts

    Posted 19 Jan 2010 Link to this post

    Hi Hector,

    Ok lets try dig into the problem . I am sending a project with the code demonstrated in action . To test it - start the application and click on the column header.  Here it seems to work as expected without exceptions. Then please try this with your data ...in case the problem persists I will need to have a look at your data and try debugging it further.

    Regards,
    Pavel Pavlov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  12. Ludovic Gerbault
    Ludovic Gerbault avatar
    226 posts
    Member since:
    Apr 2009

    Posted 19 Jan 2010 Link to this post

    Quick question on a smiliar matter, is it also possible to filter numerically on a string field ?

    (for example, try having the items where the salary is greater than 1500€ when in the source collection, the datamember field has a datatype string)
  13. Pavel Pavlov
    Admin
    Pavel Pavlov avatar
    2039 posts

    Posted 19 Jan 2010 Link to this post

    Hi Subileau Pascal,

    I believe it is theoretically  possible with filtering  but it would become rather more complicated than the sorting scenario. It will involve providing custom filtering ui template and other hacks so I would definitely recommend to place numeric data in numeric columns , rather taking the wrong way.

    Kind regards,
    Pavel Pavlov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  14. Ludovic Gerbault
    Ludovic Gerbault avatar
    226 posts
    Member since:
    Apr 2009

    Posted 19 Jan 2010 Link to this post

    the thing is that I might not have a choice, I'm up for heavy programming either way, and I'm not sure that the hacks you mentionned are any heavier than what I have to do to have a numeric field on my collection
  15. Neerajan
    Neerajan avatar
    10 posts
    Member since:
    Dec 2011

    Posted 02 Jan 2012 Link to this post

    Hello,

    In my case, I need to sort the strings 

    123456789-0
    321654789-0
    154789632-1
    :  :
    :  :
    874562126-0

    These values are in string format but i need to sort them numerically. Any suggestions regarding this?

    Regards
    Neerajan Lamsal
  16. Yen-Sheng
    Yen-Sheng avatar
    13 posts
    Member since:
    Aug 2011

    Posted 18 Sep 2012 Link to this post

    You're probably better off binding your table items to an object with types that implement IComparable. That's what I've done.
Back to Top
DevCraft banner