2016-09-12 7 views
1

я сделал заявление, что получить какое-то событие запланировано из Интернета, это событие вставляется внутри ListView, этот список организовать содержание в GroupDescription так:Фильтр ObservableCollection в пользовательском интерфейсе?

<CollectionViewSource Source="{Binding Matches}" x:Key="GroupedItems"> 
     <CollectionViewSource.GroupDescriptions> 
      <PropertyGroupDescription PropertyName="MatchNation" /> 
      <PropertyGroupDescription PropertyName="MatchLeague" /> 
     </CollectionViewSource.GroupDescriptions> 
</CollectionViewSource> 

Теперь, я имею в TextBox где использование может поиск определенного элемента внутри коллекции Matches, то, что я пытаюсь достичь, - это фильтр коллекции с заданной строкой search, предоставленной пользователем в TextBox.

Что я сейчас делаю, это механик, который использует linq, создайте резервную копию коллекции и удалите все элементы, которые не соответствуют строке пользователя search, но я заметил, что этот код слишком тяжелый, а также слишком много кода для достижения простого фильтра пользовательского интерфейса.

Мне интересно, возможно ли создать что-то вроде xaml. Таким образом, по существу у меня есть привязка в xaml к свойству, которое получает строку поиска, предоставленную TextBox, и когда значение изменилось, коллекция Matches будет отфильтрована по искомому тексту, все это через xaml.

Возможно ли это?

Пример

Предметы avaialble в Matches:

  • Здравствуйте
  • Мир

Поиск пользователя в TextBox => Hello:

в ListView будет отображаться только Hello.

ответ

0

С производительностью вам, вероятно, придется попробовать несколько вещей и просто измерить фактические результаты, чтобы найти лучший ответ. Однако, я думаю, использование обратного вызова Filter в CollectionViewSource имеет большой смысл. В принципе, вы просто присвоили бы свойству Filter обратный вызов, который принимает элемент из источника и возвращает bool, чтобы определить, следует ли его отображать. Вот пример:

// Create a view of your data, the listview should be bound to this too 
ICollectionView _matchesView = CollectionViewSource.GetDefaultView(Matches); 
// assign the Filter callback to setup filtering 
_matchesView.Filter = FilterMatches; 

// write the callback method, which returns true for items to display and false for items to hide 
private bool MatchFilter(object item) 
{ 
    // you can put any logic you need in here 
    var match = item as string; 
    return match.Contains(_searchQuery); 
} 

Если исходная коллекция или изменения поисковых запросов, то вам необходимо обновить источник просмотра коллекции тоже. Например, если у вас есть свойство FilterString, которое связано с тем, где пользователь вводит свой поисковый запрос, вы можете сделать что-то подобное в настройщике. Дело в том, что вам нужно позвонить Refresh(), когда что-то изменится.

public string FilterString 
{ 
    get { return _filterString; } 
    set 
    { 
     _filterString = value; 
     NotifyPropertyChanged(nameof(FilterString)); 
     _matchesView.Refresh(); 
    } 
} 

Основное изменение, что ваши ListView потребности быть связанным с источником просмотра коллекции использовать фильтрацию, встроенную в этот объект. В противном случае ваш список не будет отфильтрован, если он все еще привязан к фактической коллекции. Вы могли бы просто сделать источником представления свойство в вашей модели или коде зрения, стоящей за точкой зрения.

+0

Я должен объявить ObservableCollection статичным, если я использую .GetDefaultView, почему? – AgainMe

+0

Вам не нужно статически ставить его.Это должно быть примерно так: 'ObservableCollection _matches = new ObservableCollection (); var cvs = CollectoinViewSource.GetDefaultView (_matches); cvs.Filter = ... 'Метод GetDefaultView() является статическим, но вы можете передать ему нестатический аргумент. – rmc00

+0

Хорошо, to .Filter Мне нужно передать свойство, как 'FilterString', как в примере? – AgainMe

Смежные вопросы