Sort and Search ItemsSource in WPF

在WPF中我们经常会使用ListBox或者ListView来绑定我们的数据集合,这些列表通常也都会有搜索和排序的功能。下面我们就来介绍一下WPF中应该如何对数据源进行排序和搜索。

首先看一下我们要达到的功能,见图:

image

界面中是一个人员列表,右上角显示了列表中的人员数量,顶上有一个搜索栏,当用户输入字符后能自动进行关键字搜索。如下图:

image

当用户输入“王 1”,自动将姓名和电话中出现过(王)和(1)的记录搜索出来,并且右上角显示人员数量。

通过点击列眉可以对列表进行排序控制,如图:

image

 

实现过程:

1. 按照通常的做法,我们先创建一个Model类(class Member),其中包含(Name和Phone)两个属性。

public class Member {
        public string Name { get; set; }
        public string Phone { get; set; }
    }

2. 然后再创建一个数据集合(ObservableCollection<Member>)用于保存我们的人员库。

private ObservableCollection<Member> list = new ObservableCollection<Member>();

    list.Add(new Member() { Name = "张三", Phone = "13579" });
    list.Add(new Member() { Name = "李四", Phone = "24680" });
    list.Add(new Member() { Name = "王五", Phone = "43452" });
    list.Add(new Member() { Name = "王一", Phone = "79897" });
    list.Add(new Member() { Name = "王大力", Phone = "12043" });

3. 将ListBox与数据集合绑定

<ListBox x:Name="ListBoxMember" Background="#f5f5f5"
                 ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" BorderThickness="0"
                 SelectionMode="Single" ScrollViewer.CanContentScroll="False" ItemContainerStyle="{StaticResource MemberItemContainerStyle}" />
ListBoxMember.ItemsSource = list;

4. 为Member类型创建数据模板

<DataTemplate DataType="{x:Type local:Member}">
            <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="LightGray" BorderThickness="0,0,0,1">
                <UniformGrid Columns="2" Margin="5, 10">
                    <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" />
                    <TextBlock Text="{Binding Phone}" HorizontalAlignment="Center" />
                </UniformGrid>
            </Border>
    </DataTemplate>

经过1~4的步骤,我们完成了从数据到界面绑定的过程。

5. 搜索

我们已经有了一个数据源ObservableCollection<Member>,实现关键字搜索并不困难,几个判断就可以了,关键是如何绑定结果?!难道每次搜索都要创建一个结果集合然后重新做绑定吗?

答案当然是否定的。.Net提出了ICollectionView概念,这是一个视图集合,专门用于视图的排序和过滤功能。

var view = CollectionViewSource.GetDefaultView(ListBoxMember.ItemsSource);

以下是模糊关键字搜索功能的具体实现:

string text = KeywordBox.Text.Trim().ToLower();
    var view = CollectionViewSource.GetDefaultView(ListBoxMember.ItemsSource);
    if (string.IsNullOrEmpty(text)) {
        view.Filter = null;
        return;
    }

    string[] keyList = text.Split(' ');
    view.Filter = new Predicate<object>((p) => {
        bool result = true;

        foreach (string key in keyList) {
            Member m = p as Member;
            if (m.Phone.ToLower().Contains(key)) continue;
            if (m.Name.ToLower().Contains(key)) continue;
            result = false;
        }

        return result;
    });

6. 排序

同样的通过ICollectionView接口可以实现针对属性的排序控制。

var view = CollectionViewSource.GetDefaultView(ListBoxMember.ItemsSource);
    view.SortDescriptions.Clear();

    if (IsOrderAsc) {
        view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
    } else {
        view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Descending));
    }

7. Example

代码

posted @ 2013-04-23 16:30  CanMusic  阅读(453)  评论(1编辑  收藏  举报