Search code examples
c#linqwindows-phone-8windows-phonelonglistselector

Windows Phone - LongListSelector grouped items by date and ordered by date


I have my BaseArticle class which has PublishedDate and I would like to group items by days and after that I would like to order them by date and time. For now I can group them by day and it works (I created get property PublishedDateString which returns date in string):

    public List<Group<BaseArticle>> GetArticlesGroups()
    {
        return GetItemGroups<BaseArticle>(Articles, a => a.PublishedDateString);
    }

    private static List<Group<T>> GetItemGroups<T>(IEnumerable<T> itemList, Func<T, string> getKeyFunc)
    {
        IEnumerable<Group<T>> groupList = from item in itemList
                                          group item by getKeyFunc(item) into g
                                          orderby g.Key
                                          select new Group<T>(g.Key, g);

        return groupList.ToList();
    }

I am newbie in LINQ and I don't know how can I edit my GetItemGroups method to order items by date after their grouped. Thanks


Solution

  • You're just missing another orderby statement.

    I don't have the complete BaseArticle class, so I just going to make this very simple by creating a Song/Artist class like so:

    public class sample_model
    {
        public sample_model(string artist, string song, string extra = "")
        {
            this.Artist = artist;
            this.Song = song;
            this.Extra = extra;
        }
    
        public string Artist { get; set; }
        public string Song { get; set; }
        public string Extra { get; set; }       
    }
    

    Then we going to make a list of the sample_model by doing this

    private ObservableCollection<sample_model> CreateData()
    {       
        ObservableCollection<sample_model> my_list = new ObservableCollection<sample_model>();
        my_list.Add(new sample_model("Faith + 1", "Body of Christ", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Christ Again", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "A Night With the Lord", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Touch Me Jesus", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "I Found Jesus (With Someone Else)", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Savior Self", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Christ What a Day", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Three Times My Savior", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Jesus Touched Me", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Lord is my Savior", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "I Wasn't Born Again Yesterday", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Pleasing Jesus", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Jesus (Looks Kinda Hot)", "A Track"));
        my_list.Add(new sample_model("Butters", "What What", "B Track"));
    
        // add a duplicate song for our example
        my_list.Add(new sample_model("Faith + 1", "Body of Christ", "A Track"));
    
        return my_list;
    }
    
    // create our list
    ObservableCollection<sample_model> DataSource = CreateData(); 
    

    At this point we have 2 Artist (Faith + 1 and Butters).

    We can query and group this List of data by Artist Name by doing this

    var query = from item in DataSource
                group item by item.Artist into ArtistGroup
                orderby ArtistGroup.Key
                select ArtistGroup;
    
    foreach (var ArtistGroup in query)
    {
        // this will loop twice.  Once for Butters and Once for Faith + 1
        // it will order by Key which is the Artist Name
        // so Butters will be first then Faith + 1
        // but the Songs will not be ABC order, it will be order the same way we inserted them into the list
    }
    

    Now back to your original question! You want the list to be Sort by Artist and each Artist's Song to be Sorted as well. Then you must have another orderby statement

    // before we group by item.Artist, we sort by item.Song using another `orderby`      
    var query = from item in svm.DataSource
                orderby item.Song
                group item by item.Artist into ArtistGroup
                orderby ArtistGroup.Key
                select ArtistGroup;
    
    foreach (var ArtistGroup in query)
    {
        // this will loop twice.  Once for Butters and Once for Faith + 1
        // it will order by Key which is the Artist Name
        // so Butters will be first then Faith + 1
        // this time the sub list of each Artist will have their Songs sorted as well
    
        // For example, under Faith + 1 you will see
        // "A Night With the Lord" follow by
        // "Body of Christ" (TWICE) remember we put 2 in 
    }