1

アプリケーションに「グローバル」検索/フィルター関数を実装する必要があります。DataGridまたはリストの他の実装であるかどうかにかかわらず、情報のリストを含む各ウィンドウには検索ボックスが必要です。ユーザーが検索ボックスにテキストを入力すると、検索対象のリストでそのリストがフィルタリングされます。検索ロジックを一度だけ実装したい。

ほとんどの場合、これは必ずしも難しいことではありません。その理由は、リストを含むほとんどのウィンドウが同じデータ型に基づいているためです。これらはすべてViewModelであり、これらの各ViewModelはViewModelBaseを拡張し、ViewModelBaseには検索するデータが含まれています。

初歩的な例:

public class ZoneVm : ViewModelBase
{
    // Zone specific functionality
}

public class UserVm : ViewModelBase
{
    // User specific functionality
}

public class ViewModelBase : INotifyPropertyChanged
{
    public string Name { get; set; }
    public int Value { get; set; }

    // The handy thing about the common view model base is that 
    // I can contain the model binding in a single place

    // It will be easy to search List<ZoneVm> and List<UserVm> because
    // they are both effectively List<ViewModelBase>. 
}

難しさは、私が検索しなければならない外れ値オブジェクトにあります。一部のウィンドウには、 ViewModelBaseを拡張しないオブジェクトのリストが含まれているため、検索するプロパティのこの予測可能なリストはありません。

public class PanelData // doesn't implement ViewModelBase :-(
{
    public int SerialNumber { get; set; }
    public Customer Customer { get; set; }

    // other properties that I'll have to search/filter on
}

この種のタスクに対する「ベストプラクティス」アプローチはありますか?この問題を解決するデザインパターンはありますか?2つ(およびおそらくそれ以上)の異なる種類のリストを検索/フィルタリングする必要がある場合、どのようにアプローチすればよいですか?

4

3 に答える 3

0

私のアドバイスは、基本クラスの代わりにインターフェースを作成することIViewModelBaseです。このインターフェースは空にすることができます。さらに、基本クラスを作成しますが、これは特定のオブジェクトにのみ固有です(また、抽象クラスにもなります)。

public interface IViewModelBase : INotifyPropertyChanged
{
}

public abstract class Vm : IViewModelBase 
{
        public string Name { get; set; }
        public int Value { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
}

public class ZoneVm : Vm
{
    // Zone specific functionality
}

public class UserVm : Vm
{
    // User specific functionality
}

public class PanelData : IViewModelBase
{
    public int SerialNumber { get; set; }
    public Customer Customer { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
}
于 2012-07-19T08:53:17.600 に答える
0

各データに共通の検索可能なメンバーを持たせたくないと思いますか? (これは、Ofer が言ったように、この抽象メンバーと共通の IData-Interface を使用して処理できます)

私はそれらをクエリ可能なコレクションに入れ、抽象的なファッションで検索を実装します(空白を自分で埋めてください):

class MySearchableDataListBase<T> : INotifyPropertyChanged
{
   List<T> _list = new List<T>();
   string _currentFilterString = "";

   abstract bool FilterItemPredicate(T item, string query);

   public abstract IEnumerable<T> FilteredItems
   {
      get {
         return _list.Where(i => FilterItemPredicate(i, _currentFilterString)).ToArray();
      }
   }

   public string FilterQuery
   {
      get { return _currentFilterString; }
      set {
         if (value != _currentFilterString)
         {
             _currentFilterString = value;
             OnPropertyChanged("FilterQuery");
             OnPropertyChanged("FilteredItems");
         }
      }
   }
}

これをデータのコレクションとして使用し、フィルタリング/検索用のコマンドとプロパティを提供できます。

于 2012-07-19T09:01:45.883 に答える
0

ミックスインを見てみることをお勧めします: re - mix

オブジェクトに機能を混在させることができます (多重継承に少し似ています)。
次に、インターフェイスの実装を提供し、たとえば、Window を継承し、インターフェイスを介して使用できる ViewModelBase のメソッド/プロパティを持つクラスを持つことができます。

于 2012-07-19T09:09:56.960 に答える