WPF 过滤列表框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15358113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Filter a ListBox
提问by Karl_Schuhmann
I have a ListBoxwith binding to a list of strings. I want to filter the list when I enter text in a TextBox. How can I do it?
我有一个ListBox绑定到字符串列表的绑定。当我在 .csv 文件中输入文本时,我想过滤列表TextBox。我该怎么做?
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'm binding it in XAML with:
我在 XAML 中绑定它:
ItemsSource="{Binding ElementList}"
回答by Blablablaster
CollectionViewSource class can help here. As far as I can tell it has many capabilities to filter, sort and group collections.
CollectionViewSource 类可以在这里提供帮助。据我所知,它有许多功能来过滤、排序和分组集合。
ICollectionView view = CollectionViewSource.GetDefaultView(ElementList);
view.Filter = (o) => {return o;}//here is the lambda with your conditions to filter
When you don't need any filter just set view.Filterto null.
Also check out this article on filtering
当您不需要任何过滤器时,只需设置view.Filter为null. 另请查看这篇关于过滤的文章
回答by Johan Larsson
Here is an attached property for binding a filter:
这是用于绑定过滤器的附加属性:
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>), OnByChanged));
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 OnByChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ItemsControl itemsControl &&
itemsControl.Items.CanFilter)
{
itemsControl.Items.Filter = (Predicate<object>)e.NewValue;
}
}
}
Used like this in xaml:
在 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;
}
}
回答by Joee
If you set Dictionary as itemsource to listbox use the below code to sort,
如果将 Dictionary 设置为 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");
}
The above code returns the items contaning "a".
上面的代码返回包含“a”的项目。

