0

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

令我特别困惑的是如何在各种过滤条件更改时触发视图进行过滤(请参阅下面的 _ApplyFiler())。以这种方式设置过滤器是否合适?过滤后我应该在哪里取消订阅/将其设置为 null?

干杯,贝里尔

丑陋的代码:

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;
    }

}
4

1 回答 1

1

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

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

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

HTH,
绿柱石

于 2010-10-02T16:35:15.277 回答