How to get each item in it's own group?

6 posts, 0 answers
  1. Chris
    Chris avatar
    11 posts
    Member since:
    Aug 2011

    Posted 01 May 2013 Link to this post

    Hi,

    I have a list of items that I want to get in their own group. Essentially they each have their own header, and then it's content can be a few screens long, so using the JumpList with sticky headers enabled seemed to be the ideal solution.

    The headers are not simple things, they are essentially a URL to an image, a name, and a date, so I am passing in the entire object to be the header.

    What I have at the moment is - the header formats correctly, however everything seems to be grouped under the one item.

    A bit of code that constructs the list

    var listbox = new RadJumpList
    {
      Margin = new Thickness(0, 0, -12, 0),
      ItemTemplate = Resources["templateFeed"] as DataTemplate,
      StickyHeaderTemplate = Resources["templateFeedHeader"] as DataTemplate,
      GroupHeaderTemplate = Resources["templateFeedHeader"] as DataTemplate,
      IsAsyncBalanceEnabled = false,
    };
     
    var selector = new GenericGroupDescriptor<MyViewModel, MyViewModel>(x => x);               
    listbox.GroupDescriptors.Add(selector);
     
    listbox.IsGroupPickerEnabled = false;
    listbox.IsStickyHeaderEnabled = true;
    listbox.Tap += lst_Tap;
     
    listbox.ItemsSource = App.ViewModel.MyViewModel;

    The MyViewModel has the following methods on it

    public int CompareTo(MyViewModel other)
    {
        return String.Compare(other.Id, Id, StringComparison.Ordinal);
    }
     
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((MyViewModel)obj);
    }


    protected bool Equals(MyViewModel other)
    {
        return string.Equals(UserImageUrl, other.UserImageUrl) && string.Equals(Id, other.Id);
    }


    I am completely at a loss now, as to what to do to get them to have their own headers. Am I missing something else? Thanks!
  2. Chris
    Chris avatar
    11 posts
    Member since:
    Aug 2011

    Posted 01 May 2013 Link to this post

    Should say, I renamed the variables to make it more generic / easier to read...

    The line:
    listbox.ItemsSource = App.ViewModel.MyViewModel;

    should actually be more along the lines of
    listbox.ItemsSource = App.ViewModel.EnumerableOfMyViewModel;

  3. DevCraft banner
  4. Chris
    Chris avatar
    11 posts
    Member since:
    Aug 2011

    Posted 01 May 2013 Link to this post

    I am also overriding the following in the view model, but it NEVER gets called

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
  5. Chris
    Chris avatar
    11 posts
    Member since:
    Aug 2011

    Posted 01 May 2013 Link to this post

    I think I may have narrowed it down... It seems to be if I bind the source to an observable collection, and then update it after setting the ItemsSource, then it doesn't display the headers correctly.

    I've managed to re-create it with a previous example that was given for someone else.

    Is there any way to re-force the headers to be re-created?

    public partial class MainPage : PhoneApplicationPage
    {
     
        SortedObservableCollection<ChannelGroup> source = new SortedObservableCollection<ChannelGroup>();
     
        // Constructor
        public MainPage()
        {
            InitializeComponent();
     
            var nowdg = new GenericGroupDescriptor<ChannelGroup, ChannelGroup>();
            nowdg.KeySelector = (ChannelGroup channelGroup) => {
                return channelGroup;
            };
     
            nowdg.SortMode = ListSortMode.None;
     
            // COMMENT THE NEXT FOUR LINES, AND UNCOMMENT THE FOUR BELOW TO BREAK IT
            //for (int i = 0; i < 200; i++)
            //{
                //source.Add(new ChannelGroup() { ChannelName = "Name " + i, ChannelUrl = "http://www.uri.com" });
            //}
     
            this.radJumpList.GroupDescriptors.Add(nowdg);
            this.radJumpList.ItemsSource = source;
            this.radJumpList.IsStickyHeaderEnabled = true;
     
            // UNCOMMENT THIS TO BREAK IT
            for (int i = 0; i < 200; i++)
            {
                source.Add(new ChannelGroup() { ChannelName = "Name " + i, ChannelUrl = "http://www.uri.com" });
            }
     
        }
    }
     
    public class ChannelGroup : IComparable<ChannelGroup>
    {
     
        public string ChannelName { get; set; }
     
        public string ChannelUrl { get; set; }
     
        public Uri ImageUri
        {
            get
            {
                return new Uri("ApplicationIcon.png", UriKind.RelativeOrAbsolute);
            }
        }
     
        public int CompareTo(ChannelGroup other)
        {
            return -1;
        }
     
        public override bool Equals(object obj)
        {
            if (!(obj is ChannelGroup))
            {
                return false;
            }
     
            return (obj as ChannelGroup).ChannelName[(obj as ChannelGroup).ChannelName.Length - 1] == this.ChannelName[this.ChannelName.Length - 1];
        }
     
        public override int GetHashCode()
        {
            return this.ChannelName[this.ChannelName.Length - 1];
        }
    }
  6. Chris
    Chris avatar
    11 posts
    Member since:
    Aug 2011

    Posted 01 May 2013 Link to this post

    Sorry to keep posting! But I think I found a way to force it to re-gen the headers, by calling RefreshData() on the list. Is that the correct way of doing?
  7. Deyan
    Admin
    Deyan avatar
    2039 posts

    Posted 06 May 2013 Link to this post

    Hello Chris,

    Thanks for writing and for sharing the code snippets.

    The RefreshData method reevaluates the grouping of all data items which is kind of slow for greater amount of items in your source. Normally, if you are correctly implementing the INotifyPropertyChanged interface in your View Models the RadJumpList should automatically detect data changes and reevaluate the data operations in an optimized way.

    Since based on the code snippets I am not quite sure what's going on, I would like to kindly ask you for a sample project that I can use to debug the scenario and see how I can help.

    You will need to open a new support ticket in order to be able to attach the project.

    Thanks for your time.

    Regards,
    Deyan
    the Telerik team
    Have a suggestion or face a problem - you can use the Ideas & Feedback portal to submit ideas, feedback and vote for them.
Back to Top
DevCraft banner