CollectionViewSource过滤逻辑

时间:2010-09-28 22:01:19

标签: wpf silverlight filtering collectionviewsource

我提出的用于过滤的设计充其量是笨拙的,最糟糕的是错误。我们的想法是拥有一个支持选择列表的基类,并让子类根据需要添加额外的过滤逻辑。

对我来说特别困惑的是如何在各种过滤条件发生变化时触发视图过滤(请参阅下面的_ApplyFiler())。设置过滤器是否合适?在过滤后我应该在哪里取消订阅/设置为空?

干杯, Berryl

丑陋的代码:

public class SubjectPickerBase<T> : ViewModelBase, ISubjectPicker<T> 
    where T : class, IAvailableItem, INotifyPropertyChanged, IActivitySubject
{
    public CollectionViewSource Subjects { get; private set; }

    protected SubjectPickerBase() { }

    protected void _Initialize(IEnumerable<T> subjects, string subjectName) {
        ...

        Subjects = new CollectionViewSource { Source = subjects };
        _ApplyFilter();
    }

    protected void _ApplyFilter() {
        Subjects.View.Filter += Filter;
    }

    private bool Filter(object obj)
    {
        var subject = obj as T;
        if (ReferenceEquals(subject, null)) return false;

        NotifyPropertyChanged(() => Status);

        var isIncludedBySubclass = OnFilter(subject);
        var isIncludedByBase = subject.IsAvailable;
        return isIncludedByBase & isIncludedBySubclass;
    }

    /// <summary>Hook to allow implementing subclass to provide it's own filter logic</summary>
    protected virtual bool OnFilter(T subject) { return true; }


 }

public class ProjectSelectionViewModel : SubjectPickerBase<ProjectViewModel>
{

    public ProjectSelectionViewModel(IEnumerable<ProjectViewModel> projects) 
    {
        ...
        _Initialize(projects, Strings.ActivitySubject__Project);
    }

    public string DescriptionMatchText {
        get { return _descriptionMatchText; }
        set {
            ApplyPropertyChange<ProjectSelectionViewModel, string>(ref _descriptionMatchText, x => x.DescriptionMatchText, value);
            _ApplyFilter();
        }
    }
    private string _descriptionMatchText;

    protected override bool OnFilter(ProjectViewModel subject)
    {
        ...
        var isDescriptionMatch = subject.IsMatch_Description(DescriptionMatchText);
        return isPrefixMatch && isMidfixMatch && isSequenceNumberMatch && isDescriptionMatch;
    }

}

1 个答案:

答案 0 :(得分:1)

对于我缺少的视图的非平凡操作有几个部分,所有这些都与刷新CollectionViewSource属性的CollectionView有关:

我的问题的第一部分是何时设置过滤器。对于我的用例,到目前为止最有效的方法是注册CollectionViewSource.Filter事件,然后每次更改过滤器时使用View.Refresh方法。过滤器事件的初始注册也会触发事件处理程序,您看到的许多msdn示例都将此视为过滤视图的一种方式,而不是其他任何内容。但如果你的情景不是微不足道的话。用户可以更改一些过滤条件,您需要使用上述一个或多个刷新相关方法&amp;属性。

我的问题的第二部分与您是否需要取消订阅过滤器事件有关,如果是,则何时。好吧,事实证明你没有需要取消订阅,但如果这样做,它会有效地清除对视图的任何过滤。许多msdn琐碎的样本正是为了清除过滤器而做的,如果你想完全清除任何过滤,这当然是要走的路,但是对于我的用例并不是我真正想要的。我想要的是清除一些标准而不是其他标准,所以再次使用Refresh(在适当的时候)给了我想要的行为。

HTH,
Berryl