LongListSelector grouping using CollectionView in Windows Phone 7 or Windows Phone 8

∥☆過路亽.° 提交于 2019-12-10 09:22:23

问题


I am facing the same problem as listed in the below tag

Is it possible to use CollectionView with LongListSelector for grouping?

I use the following code to bind the LongListSelector with grouping.

CollectionViewSource cv = new CollectionViewSource();
cv.Source = comments;
cv.GroupDescriptions.Add(new PropertyGroupDescription("Filter"));

listSelector.HideEmptyGroups = true;
listSelector.ItemsSource = cv.View.Groups;

But it does not display anything. Anyone can you please help me on this ?


回答1:


It doesn't support ICollectionView by design. The control expects that a group implements IEnumerable which CollectionViewGroup doesn't. CollectionViewGroup is the base class for all ICollectionView groups.

So you have to make a wrapper around ICollectionView to provide support for the interfaces LongListSelector expects or modify the LongListSelector source code.

Here is my quick and dirty implementation of the wrapper:

namespace PresentationModel
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Data;

    public class GroupViewItem : IList, INotifyCollectionChanged
    {
        private readonly CollectionViewGroup group;

        public GroupViewItem(CollectionViewGroup group)
        {
            this.group = group;
            ((INotifyCollectionChanged)this.group.Items).CollectionChanged += HandleCollectionViewGroupChanged;

        }

        private void HandleCollectionViewGroupChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            OnCollectionChanged(e);
        }

        public object Name { get { return this.group.Name; } }

        public int Count { get { return this.group.ItemCount; } }

        public IEnumerator GetEnumerator()
        {
            return this.group.Items.GetEnumerator();
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;

        private void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
        {
            var collectionChanged = this.CollectionChanged;
            if (collectionChanged != null)
            {
                collectionChanged(this, args);
            }
        }

        int IList.Add(object value)
        {
            throw new NotSupportedException();
        }

        void IList.Clear()
        {
            throw new NotSupportedException();
        }

        bool IList.Contains(object value)
        {
            throw new NotSupportedException();
        }

        int IList.IndexOf(object value)
        {
            throw new NotSupportedException();
        }

        void IList.Insert(int index, object value)
        {
            throw new NotSupportedException();
        }

        bool IList.IsFixedSize
        {
            get
            {
                throw new NotSupportedException();
            }
        }

        bool IList.IsReadOnly
        {
            get
            {
                throw new NotSupportedException();
            }
        }

        void IList.Remove(object value)
        {
            throw new NotSupportedException();
        }

        void IList.RemoveAt(int index)
        {
            throw new NotSupportedException();
        }

        object IList.this[int index]
        {
            get
            {
                throw new NotSupportedException();
            }
            set
            {
                throw new NotSupportedException();
            }
        }

        void ICollection.CopyTo(System.Array array, int index)
        {
            throw new NotSupportedException();
        }

        bool ICollection.IsSynchronized
        {
            get
            {
                throw new NotSupportedException();
            }
        }

        object ICollection.SyncRoot
        {
            get
            {
                throw new NotSupportedException();
            }
        }
    }

    public class GroupView : IEnumerable, INotifyCollectionChanged
    {
        private readonly ICollectionView collectionView;
        private readonly List<GroupViewItem> items;

        public GroupView(ICollectionView collectionView)
        {
            this.items = new List<GroupViewItem>();

            this.collectionView = collectionView;
            ((INotifyCollectionChanged)this.collectionView.Groups).CollectionChanged += HandleCollectionViewGroupsChanged;
            ResetGroups(notify: false);
        }

        private void HandleCollectionViewGroupsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    AddGroups(e);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    RemoveGroups(e);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    ReplaceGroups(e);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    ResetGroups();
                    break;
            }
        }

        private IList<GroupViewItem> AddGroups(NotifyCollectionChangedEventArgs e, bool notify = true)
        {
            var newGroups = e.NewItems
                .Cast<CollectionViewGroup>()
                .Select(cvg => new GroupViewItem(cvg))
                .ToArray();

            this.items.InsertRange(e.NewStartingIndex, newGroups);

            if (notify)
            {
                for (var i = 0; i != newGroups.Length; ++i)
                {
                    OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                        NotifyCollectionChangedAction.Add,
                        newGroups[i],
                        e.NewStartingIndex + i));
                }
            }

            return newGroups;
        }

        private IList<GroupViewItem> RemoveGroups(NotifyCollectionChangedEventArgs e, bool notify = true)
        {
            var oldGroups = this.items.GetRange(e.OldStartingIndex, e.OldItems.Count);

            this.items.RemoveRange(e.OldStartingIndex, e.OldItems.Count);

            if (notify)
            {
                for (var i = 0; i != oldGroups.Count; ++i)
                {
                    OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                        NotifyCollectionChangedAction.Remove,
                        oldGroups[i],
                        e.OldStartingIndex + i));
                }
            }

            return oldGroups;
        }

        private void ReplaceGroups(NotifyCollectionChangedEventArgs e)
        {
            var oldGroups = RemoveGroups(e, notify: false);
            var newGroups = AddGroups(e, notify: false);

            if (oldGroups.Count != newGroups.Count)
            {
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                    NotifyCollectionChangedAction.Reset));
            }
            else
            {
                for (var i = 0; i != newGroups.Count; ++i)
                {
                    OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                        NotifyCollectionChangedAction.Replace,
                        newGroups[i], oldGroups[i],
                        e.NewStartingIndex + i));
                }
            }
        }

        private void ResetGroups(bool notify = true)
        {
            this.items.Clear();
            this.items.AddRange(
                this.collectionView.Groups
                    .Cast<CollectionViewGroup>()
                    .Select(cvg => new GroupViewItem(cvg)));

            if (notify)
            {
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                    NotifyCollectionChangedAction.Reset));
            }
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;

        public IEnumerator GetEnumerator()
        {
            return this.items.GetEnumerator();
        }

        private void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
        {
            var collectionChanged = this.CollectionChanged;
            if (collectionChanged != null)
            {
                collectionChanged(this, args);
            }
        }
    }
}


来源:https://stackoverflow.com/questions/14251274/longlistselector-grouping-using-collectionview-in-windows-phone-7-or-windows-pho

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!