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 サンプルの多くは、これをビューをフィルター処理する方法として示しています。ただし、シナリオが簡単ではなく、ユーザーがフィルター条件を変更できる場合は、上記の更新関連のメソッドとプロパティを 1 つ以上使用する必要があります。

私の質問の 2 番目の部分は、フィルター イベントのサブスクライブを解除する必要があるかどうか、また、そうであればいつ解除するかに関するものでした。サブスクリプションを解除する必要がないことがわかりましたが、そうすると、ビューのフィルタリングが効果的にクリアされます。そして、msdn の簡単なサンプルの多くは、フィルターをクリアするために正確にそれを行います。これは、フィルター処理を完全にクリアしたい場合に確実に実行する方法ですが、私の使用例では、私が本当に望んでいたものではありませんでした。私が望んでいたのは、いくつかの基準をクリアし、他の基準をクリアしないことでした。そのため、(適切なタイミングで) Refresh を再度使用すると、望ましい動作が得られました。

HTH、
ベリル

于 2010-10-02T16:35:15.277 に答える