【问题标题】:ICollectionView Filter issue wpf c#ICollectionView过滤器问题wpf c#
【发布时间】:2017-10-05 15:24:23
【问题描述】:

我正在尝试过滤 ICollection,但未应用过滤器,而是为我提供了所有记录。谓词有什么问题吗?所以有两种方法可以在收集上应用过滤器。首先它过滤 SW_Version 的记录,然后在第二个过滤器中过滤匹配的 id。基本上我正在实现搜索功能。

   public void Updateswlist()
    {
        CRmappings2 = new ObservableCollection<SPFetchCREntity>(crentities.ToList());
        AllCRSP = CollectionViewSource.GetDefaultView(CRmappings2);
        SearchMU = SelectedSW.SW_Version;
        AllCRSP.Filter = obj =>
        {
            SPFetchCREntity entity = obj as SPFetchCREntity;
            return obj != null && entity.SW_Version == SearchMU.ToString();
        };
        AllCRSP.Refresh();

第二个过滤器

        public void searchMUID()
    {
        AllCRSP.Filter = obj =>
        {
            SPFetchCREntity entity = obj as SPFetchCREntity;
            return obj != null && entity.MU_Identifier == Mupass.ToString();
        };
        AllCRSP.Refresh();
    }

【问题讨论】:

  • 您是否尝试同时按 SW_Version 和 MU_Identifier 进行过滤?
  • CVS 的源是否设置为 CRmappings2?
  • @mm8 不,它们发生在不同的屏幕上。但第二个过滤器应用于第一个过滤器的视图。

标签: c# wpf data-binding observablecollection icollectionview


【解决方案1】:

第二个过滤器覆盖第一个过滤器。如果您希望能够按这两个属性进行过滤,则需要在谓词中包含这两个条件:

public void searchMUID()
{
    string Mupass = "";
    AllCRSP.Filter = obj =>
    {
        SPFetchCREntity entity = obj as SPFetchCREntity;
        return obj != null && entity.SW_Version == SearchMU.ToString() && entity.MU_Identifier == Mupass.ToString();
    };
    AllCRSP.Refresh();
}

【讨论】:

  • 这可行,但我发现了问题。由于我在这个“public void Updateswlist()”中添加了一个过滤器,并且我再次对来自public void searchMUID() 的视图进行过滤,派生的第一个过滤器的视图已经消失,所以我无法搜索记录。假设如果我从第二种方法中清除 AllCRSP 的过滤器,它是否也会清除第一种方法的所有过滤器?
【解决方案2】:

我更喜欢使用 ReactiveUI 中的 ReactiveList 及其 derived collection。它只是工作 - 无需手动触发 Refresh

public class TweetsListViewModel : ReactiveObject
{
    ReactiveList<Tweet> Tweets = new ReactiveList<Tweet>();

    IReactiveDerivedList<TweetTileViewModel> TweetTiles;
    IReactiveDerivedList<TweetTileViewModel> VisibleTiles;

    public TweetsListViewModel()
    {
        TweetTiles = Tweets.CreateDerivedCollection(
            x => new TweetTileViewModel() { Model = x },
            x => true,
            (x, y) => x.CreatedAt.CompareTo(y.CreatedAt));

        VisibleTiles = TweetTiles.CreateDerivedCollection(
            x => x,
            x => !x.IsHidden);
    }
}

如果 SPFetchCREntity 没有实现 INotifyPropertyChanged,您可以使用可观察到的 reset 参数创建衍生集合。每次打勾时,整个列表都会被过滤

【讨论】:

    【解决方案3】:

    这就是我解决双过滤器问题的方法。我从这个链接https://code.msdn.microsoft.com/windowsdesktop/CollectionView-Tips-MVVM-d6ebb4a7得到了这个想法

            public void searchMUID()
        {
            Muview = (CollectionView)new CollectionViewSource { Source = CRmappings2 }.View; //CRmappings2 is an observable collection and Muview is a public property of collectionview
            //FirstCRSP = AllCRSP;
    
            //muview.Filter = null;
    
            Muview.Filter = obj =>
            {
                SPFetchCREntity entity = obj as SPFetchCREntity;
                return obj != null && entity.SW_Version == SearchMU.ToString() && entity.MU_Identifier == Mupass.ToString();
            };
            Muview.Refresh();
        }
    

    【讨论】:

    • 这个答案和我的有什么区别?
    • @mm8 我已经添加了这个额外的行Muview = (CollectionView)new CollectionViewSource { Source = CRmappings2 }.View; 这过滤了可观察的集合而不是 icollection,这样我可以保留应用于 icollection 的过滤器
    • new CollectionViewSource 创建一个新的 CollectionViewSource,然后您将其转换为 CollectionView,仅此而已。
    • 您的实际问题的答案是您必须在谓词中包含这两个条件。
    • @mm8 我怎样才能把它放到列表中AllCRSP = CollectionViewSource.GetDefaultView(CRmappings2);
    猜你喜欢
    • 2016-04-07
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多