2013-03-12 14 views
8

Załaduję listę ciągów w moim ListBox, teraz chcę ją filtrować po wprowadzeniu tekstu w TextBox. Jak mogę to zrobić?Filtr WPF ListBox

public void ListLoad() 
{ 
    ElementList = new List<string>(); // creation a list of strings 
    ElementList.Add("1"); // add a item of string 
    ElementList.Add("2"); // add a item of string 

    DataContext = this; // set the data context 
} 

Jestem wiązania go w XAML z:

ItemsSource = "{Binding ElementList}"

Odpowiedz

23

klasa CollectionViewSource może pomóc tutaj. O ile mogę powiedzieć, ma wiele możliwości filtrowania, sortowania i grupowania kolekcji.

ICollectionView view = CollectionViewSource.GetDefaultView(ElementList); 
view.Filter = (o) => {return o;}//here is the lambda with your conditions to filter 

Kiedy nie potrzeba żadnego filtra wystarczy ustawić view.Filter do null. również sprawdzić ten artykuł na filtering

0

Jeśli ustawisz Dictionary jako ItemSource do listbox użyć poniższego kodu do sortowania,

private void tb_filter_textChanged(object sender, TextChangedEventArgs e) 
    { 
     Dictionary<string, string> dictObject = new Dictionary<string, string>(); 
     ICollectionView view = CollectionViewSource.GetDefaultView(dictObject); 
     view.Filter = CustomerFilter; 
     listboxname.ItemsSource = view; 
    } 

    private bool CustomerFilter(object item) 
    { 
     KeyValuePair<string, string> Items = (KeyValuePair<string,string>) item; 
     return Items.Value.ToString().Contains("a"); 
    } 

Powyższy kod zwraca elementy contaning „A”.

7

Oto załączony właściwość do wiązania filtr:

using System; 
using System.Windows; 
using System.Windows.Controls; 

public static class Filter 
{ 
    public static readonly DependencyProperty ByProperty = DependencyProperty.RegisterAttached(
     "By", 
     typeof(Predicate<object>), 
     typeof(Filter), 
     new PropertyMetadata(default(Predicate<object>), OnWithChanged)); 

    public static void SetBy(ItemsControl element, Predicate<object> value) 
    { 
     element.SetValue(ByProperty, value); 
    } 

    public static Predicate<object> GetBy(ItemsControl element) 
    { 
     return (Predicate<object>)element.GetValue(ByProperty); 
    } 

    private static void OnWithChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     UpdateFilter((ItemsControl)d, (Predicate<object>)e.NewValue); 
    } 

    private static void UpdateFilter(ItemsControl itemsControl, Predicate<object> filter) 
    { 
     if (itemsControl.Items.CanFilter) 
     { 
      itemsControl.Items.Filter = filter; 
     } 
    } 
} 

używane jak to w XAML:

<DataGrid local:Filter.By="{Binding Filter}" 
      ItemsSource="{Binding Foos}"> 
    ... 

I viewmodel:

public class ViewModel : INotifyPropertyChanged 
{ 
    private string filterText; 
    private Predicate<object> filter; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public ObservableCollection<Foo> Foos { get; } = new ObservableCollection<Foo>(); 

    public string FilterText 
    { 
     get { return this.filterText; } 
     set 
     { 
      if (value == this.filterText) return; 
      this.filterText = value; 
      this.OnPropertyChanged(); 
      this.Filter = string.IsNullOrEmpty(this.filterText) ? (Predicate<object>)null : this.IsMatch; 
     } 
    } 

    public Predicate<object> Filter 
    { 
     get { return this.filter; } 
     private set 
     { 
      this.filter = value; 
      this.OnPropertyChanged(); 
     } 
    } 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    private bool IsMatch(object item) 
    { 
     return IsMatch((Foo)item, this.filterText); 
    } 

    private static bool IsMatch(Foo item, string filterText) 
    { 
     if (string.IsNullOrEmpty(filterText)) 
     { 
      return true; 
     } 

     var name = item.Name; 
     if (string.IsNullOrEmpty(name)) 
     { 
      return false; 
     } 

     if (filterText.Length == 1) 
     { 
      return name.StartsWith(filterText, StringComparison.OrdinalIgnoreCase); 
     } 

     return name.IndexOf(filterText, 0, StringComparison.OrdinalIgnoreCase) >= 0; 
    } 
} 
Powiązane problemy