我们已经使用ListView做了几件不同的事情,比如分组和排序,但另一个非常有用的功能是过滤。显然,您可以首先限制添加到ListView的项目,但通常需要在运行时动态过滤ListView,通常基于用户输入的过滤器字符串。对我们来说幸运的是,ListView的视图机制也很容易做到这一点,就像我们通过排序和分组一样。
过滤实际上很容易,所以让我们直接跳到一个例子中,然后我们将讨论它:
<Window x:Class="WpfTutorialSamples.ListView_control.FilteringSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FilteringSample" Height="200" Width="300">
<DockPanel Margin="10">
<TextBox DockPanel.Dock="Top" Margin="0,0,0,10" Name="txtFilter" TextChanged="txtFilter_TextChanged" />
<ListView Name="lvUsers">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
</ListView>
</DockPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;
namespace WpfTutorialSamples.ListView_control
{
public partial class FilteringSample : Window
{
public FilteringSample()
{
InitializeComponent();
List<User> items = new List<User>();
items.Add(new User() { Name = "John Doe", Age = 42 });
items.Add(new User() { Name = "Jane Doe", Age = 39 });
items.Add(new User() { Name = "Sammy Doe", Age = 13 });
items.Add(new User() { Name = "Donna Doe", Age = 13 });
lvUsers.ItemsSource = items;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
view.Filter = UserFilter;
}
private bool UserFilter(object item)
{
if(String.IsNullOrEmpty(txtFilter.Text))
return true;
else
return ((item as User).Name.IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0);
}
private void txtFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
CollectionViewSource.GetDefaultView(lvUsers.ItemsSource).Refresh();
}
}
public enum SexType { Male, Female };
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Mail { get; set; }
public SexType Sex { get; set; }
}
}
XAML部分非常简单:我们有一个TextBox,用户可以在其中输入搜索字符串,然后使用ListView来显示结果。
在Code-behind中,我们首先向ListView添加一些User对象,就像我们在前面的例子中所做的那样。有趣的部分发生在构造函数的最后两行中,我们获取对ListView的CollectionView实例的引用,然后将委托分配给Filter属性。这个委托指向名为UserFilter的函数,我们在下面实现了它。它将每个项目作为第一个(也是唯一的)参数,然后返回一个布尔值,指示给定项目是否应该在列表中可见。
在UserFilter()方法中,我们看看TextBox控件(txtFilter),看看它是否包含任何文本 - 如果是,我们用它来检查User的名称(这是我们的属性)已经决定过滤)包含输入的字符串,然后根据它返回true或false。如果TextBox为空,则返回true,因为在这种情况下,我们希望所有项都可见。
txtFilter_TextChanged事件也很重要。每次文本更改时,我们都会获得对ListView的View对象的引用,然后在其上调用Refresh()方法。这可确保每次用户更改搜索/过滤字符串文本框的值时都会调用过滤器委托。
这是一个非常简单的实现,但由于您可以访问每个项目,在本例中是User类,您可以进行任何类型的自定义过滤,因为您可以访问有关每个项目的所有数据在列表中。例如,通过查看Age属性而不是Name属性,上面的示例可以很容易地更改为过滤年龄,或者您可以修改它以查看多个属性,例如筛选出年龄低于X且名称不包含“Y”的用户。
(c) 2024 chaojicainiao.com MIT license