首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何处理具有CollectionView特性的CompositeCollection?

如何处理具有CollectionView特性的CompositeCollection?
EN

Stack Overflow用户
提问于 2010-01-17 08:50:07
回答 3查看 5.7K关注 0票数 7

有没有办法在CompositeCollection的当前位置改变时得到通知?

我需要有一个CollectionView监控的CompositeCollection,任何想法都是欢迎的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-01-17 09:00:53

您可以通过监视CollectionView的ICollectionView.CurrentChanged事件来检测当前项何时发生更改。以下代码适用于我:

代码语言:javascript
复制
CompositeCollection cc = new CompositeCollection();
cc.Add(new CollectionContainer { Collection = new string[] { "Oh No!", "Fie" } });
cc.Add(new CollectionContainer { Collection = new string[] { "Zounds", "Ods Bodikins" } });
CollectionViewSource cvs = new CollectionViewSource { Source = cc };

// Subscribing to CurrentChanged on the ICollectionView
cvs.View.CurrentChanged += (o, e) => MessageBox.Show("current changed");

lb.ItemsSource = cvs.View;  // lb is a ListBox with IsSynchronizedWithCurrentItem="True"

当我在ListBox中更改选择时,将显示消息框。

关于过滤、排序和分组,根据Aron的回答,这些在CompositeCollection上的视图中是不可用的。但需要注意的是,您可以通过以下方式来检测支持这些特性的视图的更改:

当过滤器改变时,看起来你会得到一个CollectionChanged事件,尽管我找不到这个documented.

  • SortDescriptions is SortDescriptionCollection,它是INotifyCollectionChanged,所以在CollectionChanged property.

  • GroupDescriptions is ObservableCollection<GroupDescription>上挂接一个INotifyCollectionChanged事件处理程序,所以在GroupDescriptions属性上挂接一个GroupDescriptions事件处理程序。
票数 7
EN

Stack Overflow用户

发布于 2010-01-17 09:42:50

不能在复合集合上运行CollectionView,请参见here

票数 0
EN

Stack Overflow用户

发布于 2016-07-12 21:01:30

我遇到了同样的问题:我需要对CompositeCollection进行排序。我写了下面的类来解决这个问题,至少对于相同类型的ObservableCollections是这样的。

其思想是将复合集合作为普通的可观察集合进行维护,并在底层集合发生变化时对其进行更新。然后,可以在用户界面中使用得到的集合(AllNodes),并且它可以很好地支持CollectionView。

代码语言:javascript
复制
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;

namespace Util {
    public class ObservableCollectionCollector<T> {
        private class ReplacableObservableCollection : ObservableCollection<T> {
            public void Replace(int idx, T v) {
                SetItem(idx, v);
            }
        }
        private readonly ReplacableObservableCollection allNodes;
        private readonly ObservableCollection<T>[] colls;
        private readonly int[] lens;

        public ObservableCollectionCollector(params ObservableCollection<T>[] colls) {
            this.colls = colls;
            allNodes = new ReplacableObservableCollection();
            foreach (var l in colls) {
                foreach (var e in l)
                    allNodes.Add(e);
                l.CollectionChanged += HandleCollectionChanged;
            }
            lens = colls.Select(c => c.Count).ToArray();
        }

        public ReadOnlyObservableCollection<T> AllNodes {
            get { return new ReadOnlyObservableCollection<T>(allNodes); }
        }

        private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
            int i0 = 0;
            int ci = 0;
            foreach (var l in colls) {
                if (l == sender)
                    break;
                i0 += l.Count;
                ++ci;
            }
            switch (e.Action) {
                case NotifyCollectionChangedAction.Add:
                    for (int i = 0; i < e.NewItems.Count; ++i)
                        allNodes.Insert(i0 + e.NewStartingIndex + i, (T)e.NewItems[i]);
                    break;
                case NotifyCollectionChangedAction.Move:
                    for (int i = 0; i < e.OldItems.Count; ++i)
                        allNodes.Move(i0 + e.OldStartingIndex + i, i0 + e.NewStartingIndex + i);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    for (int i = 0; i < e.OldItems.Count; ++i)
                        allNodes.RemoveAt(i0 + e.OldStartingIndex);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    for (int i = 0; i < e.NewItems.Count; ++i)
                        allNodes.Replace(i0 + e.OldStartingIndex + i, (T)e.NewItems[i]);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    for (int i = 0; i < lens[ci]; ++i)
                        allNodes.RemoveAt(i0);
                    break;
            }
            lens[ci] = ((ObservableCollection<T>)sender).Count;
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2079553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档