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

我认为您不希望每个数据都有一个共同的可搜索成员吗?(这可以通过使用带有这个抽象成员的通用 IData-Interface 来处理,正如 Ofer 所说)

我会将它们放在可查询的集合中,并以抽象的方式实现搜索(请自行填写空白):

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

你可能想看看 mixins:re - mix

它允许您在对象中混合功能(有点像多继承)。
然后,您可以提供接口实现,并拥有一个继承 Window 的类,并具有 ViewModelBase 的方法/属性,可通过接口使用。

于 2012-07-19T09:09:56.960 回答