【问题标题】:How to filter ObservableCollection on multplie values如何过滤多个值的 ObservableCollection
【发布时间】:2017-11-19 18:10:52
【问题描述】:

我有一个可观察的集合。

这个集合的类有几个字段,这些字段又可以有服务器值。

我希望我的用户能够搜索大量字段和值。

我已经使用 ICollection,但我看到的所有示例都是基于对 1 个字段的搜索。

这是我的课:

public class Tasks
{
    private string JobPriority;
    private string JobLabel;
    private string JobType;
    private string UserRef;
}

JobPriority can be 'High', 'Low'
JobLabel can be 'Apple', 'Android', 'Microsoft'
JobType can be  'Internal', 'Private', 'Public' 

所以,我这样实例化我的集合:

public ObservableCollection<KanbanModelExtra> Tasks
{
    get
    {
        if (_tasks == null)
        {
            TaskView = CollectionViewSource.GetDefaultView(_tasks);
            TaskView.Filter = TaskFilter;
        }
        return _tasks;
    }
    set
    {
        _tasks = value;
    }
}
public ICollectionView TaskView { get; private set; }

并将我的过滤器设置为:

private bool TaskFilter(
    object item )
{
    var task = item as KanbanModelExtra;

    if ( task == null )
    {
        return false;
    }

    foreach ( var searchItem1 in JobPrioritiesToSearchOn )
    {
        if ( task.JobPriority == searchItem1 )
        {
            foreach ( var searchItem2 in JobLabelsToSearchOn )
            {
                if ( task.JobLabel == searchItem2)
                {
                    foreach (var searchItem3 in JobTypesToSearchOn)
                    {
                        if (task.JobType == searchItem3)
                        {
                            if ( SearchByCurrentUser )
                            {
                                if ( task.UserRef == HeartBeat.CurrentUser.UserRef )
                                {
                                    return true;
                                }
                            }
                            else
                            {
                                return true;
                            }
                        }
                    }
                }
            }
        }
    }
    return false;
}

但这似乎“沉重”且丑陋。此外,每次更改都会刷新集合。在选择了所有标准之后,我会在哪里撒谎以刷新收藏。

有没有更好的办法?

【问题讨论】:

    标签: c# wpf filter observablecollection icollection


    【解决方案1】:

    将测试链接在一起。

    var result = JobPrioritiesToSearchOn.Any(x => x == task.JobPriority);
    result = result && JobLabelsToSearchOn.Any(x => x == task.JobLabel);
    result = result && JobTypesToSearchOn.Any(x => x == task.JobType);
    
    if (SearchByCurrentUser)
    {
        result = result && task.UserRef == HeartBeat.CurrentUser.UserRef;
    }
    
    return result;
    

    如果任何集合与传入的过滤器匹配,Any() 将返回 true。用简单的英语来说,如果任何 JobPrioritiesToSearchOn 项等于 task.JobPriority,则第一行的计算结果为 true。

    【讨论】:

    • 谢谢,我将对这两个答案进行比较并回复
    • @eocron 我注意到原始逻辑取决于SearchByCurrentUser - 它可能是错误的,但true 结果仍然是所需的输出。
    • 谢谢,我也注意到了这一点。编辑了答案。
    • 嗨,我现在需要离开我的电脑 :( 我希望在两个答案之间进行速度测试。我感谢你的时间和 answer.replies 并承诺在我完成后尽快回来这个。再次感谢:)
    【解决方案2】:

    foreach 的疯狂可以用这个表达式代替:

    return ((SearchByCurrentUser && task.UserRef == HeartBeat.CurrentUser.UserRef) || !SearchByCurrentUser) &&
           JobPrioritiesToSearchOn.Contains(task.JobPriority) &&
           JobLabelsToSearchOn.Contains(task.JobLabel) &&
           JobTypesToSearchOn.Contains(task.JobType));
    

    【讨论】:

    • 嗯,看起来很简单!感谢您的回答。我会把它放进去,然后回来报告。谢谢
    • 嗨,我现在需要离开我的电脑 :( 我希望在两个答案之间进行速度测试。我感谢你的时间和 answer.replies 并承诺在我完成后尽快回来这个。再次感谢:)
    猜你喜欢
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多