私が思いついたフィルタリングの設計は、せいぜいぎこちなく、最悪の場合はバグがあります。アイデアは、選択リストをサポートする基本クラスを用意し、サブクラスが必要に応じて追加のフィルタリング ロジックを追加できるようにすることです。
私が特に混乱しているのは、さまざまなフィルタリング基準が変更されたときにビューをトリガーしてフィルタリングする方法です (以下の _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;
}
}