2013-03-12 108 views
8

我在我的ListBox中加載了一個字符串列表,現在我想在TextBox中輸入文本時對其進行過濾。我該怎麼做?WPF篩選列表框

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 
} 

我與它結合在XAML:

的ItemsSource = 「{綁定元素列表}」

回答

23

CollectionViewSource類可以幫助在這裏。據我所知,它有很多功能來過濾,排序和分組集合。

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

當你不需要任何過濾器只設置view.Filternull。 還檢查了這篇文章filtering

0

如果設置爲詞典來的ItemSource列表框使用下面的代碼進行排序,

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

上面的代碼返回contaning「一」的項目。

7

下面是一個附加屬性的綁定過濾器:

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

像這樣來使用XAML中:

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

和視圖模型:

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