【问题标题】:WPF Binding filtered ObservableCollection ICollectionView to ComboboxWPF 将过滤后的 ObservableCollection ICollectionView 绑定到 Combobox
【发布时间】:2013-06-30 05:37:08
【问题描述】:

我想根据类型(类型 AddPoint)将 ObservableCollection 过滤为子集,并希望它按升序排列,没有重复。我的基类是 ModelBase,带有子类 AddPoint、Time、Repeat 等... ObservableCollection MotionSequenceCollection 将以任何顺序填充这些类型,并且有些将是重复的。

我已经尝试了几次不同的时间,并在下面我“拉”出的 ICollectionView 属性中显示了它们:Bind subset of collection

可观察的集合

private ObservableCollection<ModelBase> _motionSequenceCollection = 
        new ObservableCollection<ModelBase>();

    public ObservableCollection<ModelBase> MotionSequenceCollection
    {
        get
        {
            return _motionSequenceCollection;
        }

        set
        {
            if (_motionSequenceCollection == value)
            {
                return;
            }

            var oldValue = _motionSequenceCollection;
            _motionSequenceCollection = value;

            // Update bindings, no broadcast
            RaisePropertyChanged();
        }
    }

    public ICollectionView Location
    {
        get
        {
             var location = CollectionViewSource.GetDefaultView(_motionSequenceCollection);

            //DOES NOT WORK.  PROBLEM: GetType() creates type of system.type() and AddPoint, which don't work.  Need a cast, or something??  
            // found at https://stackoverflow.com/questions/9621393/bind-subset-of-collection  The problem is that there is an error:
            //    Cannot apply operator '==' to operands of type 'System.Type' and 'MotionSeq.Model.AddPoint',
            //    candidates are:
            //          bool ==(System.Reflection.MemberInfo, System.Reflection.memberInfo) (in class MemberInfo)
            //          bool ==(System.type, System.Type) (in class Type)
            //location.Filter = p => (p as ModelBase).GetType() == AddPoint;

            //DOES NOT WORK.  PROBLEM: Affects the main collection and won't let TIME type added.
            //location.Filter = o1 => (o1 is AddPoint);

            //DOES NOT WORK.  PROBLEM: Sorts fine, but also sorts MotionSequenceCollection!!  What up w/ that!?  
            //location.SortDescriptions.Add(new SortDescription("AddPointClassName", ListSortDirection.Ascending));

            //DOES NOT WORK.  PROBLEM: MotionSequenceCollection does not update.
            //location.Filter = p => (p as ModelBase) == AddPoint;

            //DOES NOT WORK.  PROBLEM: Source is not instantiated(?) and exmaple from stackoverflow and not sure how that got there in the first place.
            //source.Filter = p => (p as ModelBase).GetType() == "AddPoint";
            //return source;

            return location;
        }
    }

【问题讨论】:

    标签: c# wpf mvvm-light observablecollection icollectionview


    【解决方案1】:

    所有集合都有一个默认的 CollectionView。 WPF 始终绑定到视图而不是集合。如果直接绑定到集合,WPF 实际上会绑定到该集合的默认视图。此默认视图由​​集合的所有绑定共享,这会导致集合的所有直接绑定共享一个默认视图的排序、过滤器、组和当前项特性。

    尝试创建CollectionViewSource 并将其过滤逻辑设置如下:

    //create it as static resource and bind your ItemsControl to it
    <CollectionViewSource x:Key="csv" Source="{StaticResource MotionSequenceCollection}" 
                      Filter="CollectionViewSource_Filter">
        <CollectionViewSource.GroupDescriptions>
           <PropertyGroupDescription PropertyName="YYY"/>
        </CollectionViewSource.GroupDescriptions>
        <CollectionViewSource.SortDescriptions>
             <scm:SortDescription PropertyName="YYY" Direction="Ascending"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource> 
    
    private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
    {
        var t = e.Item as ModelBase;
        if (t != null)
    
        {
            //use your filtering logic here
    
        }
    }
    

    【讨论】:

    • 老实说,我正在为此苦苦挣扎。我最初使用 CollectionViewSource_FIlter 使用 @makc 的方式并找到了一些示例来提供帮助,但问题在于使列表 distinct() - 这是 2 天前的事,我的脑袋一片模糊。过滤器是这样的:
    • 我需要修改我的评论。我确实让您的解决方案正常工作,并且学到了很多关于 collectionviewsource 的知识。问题是,如果有重复项并且组合框(过滤视图)中只显示一个,当我在集合中编辑一个时,它不会通过添加新的来更新编辑的记录。如果只有一个,则在属性更改后按预期更新。这就是为什么我后来走上了一条 linq 的道路,但事实证明那是灾难性的。
    • @FloppyDisk 我很高兴你不只是复制过去而是阅读和学习:),我不确定我是否完全理解问题尝试创建一个小的独立示例,我认为值得一个新的问题...
    【解决方案2】:

    按类型过滤很容易。这应该有效:

    location.Filter = p => p.GetType() == typeof(AddPoint);
    

    排序也很容易。您需要做的就是实现IComparer 并将其分配给集合视图的CustomSort 属性。

    没有简单的方法可以删除重复项(我不知道)。我建议你在其他地方做。例如,您可以区分您的基础集合。

    【讨论】:

    • 我改变了策略并尝试使用 LINQ 创建 observablecollection 的子集。然后将其绑定回我的视图。这是一次严重的绕行。我确实有一个错误说我需要实现 IComparer。调查那个。感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 2013-04-18
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    相关资源
    最近更新 更多