WPF Filter ListBox

I am loading a list of strings in my ListBox , now I want to filter it when I enter text in a TextBox . How can i do this?

 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 } 

I bind it in XAML with:

ItemsSource = "{Binding ElementList}"

+8
list c # wpf xaml listbox
source share
3 answers

The CollectionViewSource class can help here. As far as I can tell, it has many options for filtering, sorting, and grouping collections.

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

If you don't need any filter, just set view.Filter to null . Also check out this article on filtering

+23
source share

Here is the attached property for filter binding:

 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; } } } 

Used as in xaml:

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

And 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; } } 
+7
source share

If for Dictionary, use the following sorting code as sources for the list,

  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"); } 

The above code returns elements related to "a".

0
source share

All Articles