This article is currently in the process of being translated into Polish (~99% done).
ListView filtering
Zrobiliśmy już kilka różnych rzeczy z ListView, takich jak grupowanie i sortowanie, ale kolejną bardzo przydatną funkcją jest filtrowanie. Oczywiście można po prostu ograniczyć elementy dodawane do ListView w pierwszej kolejności, ale często trzeba filtrować ListView dynamicznie, w czasie wykonywania, zwykle na podstawie wprowadzonego przez użytkownika ciągu filtrującego. Na szczęście dla nas, mechanizmy widoku ListView również ułatwiają robienie tego, tak jak widzieliśmy to w przypadku sortowania i grupowaniem.
Filtrowanie jest w rzeczywistości dość łatwe do wykonania, więc przejdźmy od razu do przykładu, a następnie omówimy go później:
<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; }
}
}
Część XAML jest dość prosta: Mamy TextBox, w którym użytkownik może wprowadzić wyszukiwany ciąg, a następnie ListView, aby wyświetlić wynik.
W kodzie zródłowym , zaczynamy od dodania kilku obiektów User do ListView, tak jak zrobiliśmy to w poprzednich przykładach. Interesująca część dzieje się w ostatnich konstruktora, gdzie otrzymujemy referencję do CollectionView instancji dla ListView, a następnie przypisać delegata do Filter właściwości. Ten delegat wskazuje na funkcję o nazwieUserFilter, którą zaimplementowaliśmy poniżej.Przyjmuje ona przyjmuje każdy element jako pierwszy (i jedyny) parametr, a następnie zwraca wartość logiczną, która wskazuje, czy dany element powinien być widoczny na liście. liście.
W metodzie UserFilter() przyglądamy się kontrolce TextBox (txtFilter), aby sprawdzić, czy zawiera jakiś tekst - jeśli tak, używamy jej do sprawdzić, czy nazwa użytkownika (która jest właściwością, na której zdecydowaliśmy się filtrować) zawiera wprowadzony ciąg, a następnie zwrócić wartość true lub false w zależności od tego. Jeśli TextBox jest pusty, zwracamy true, ponieważ w takim przypadku chcemy, aby wszystkie elementy były widoczne.
Zdarzenie txtFilter_TextChanged jest również ważne. Za każdym razem, gdy zmienia się tekst, pobieramy odwołanie do obiektu View widoku ListView, a następnie wywołujemy metodę Refresh(). Gwarantuje to, że delegat filtra jest wywoływany za każdym razem, gdy użytkownik zmieni wartość pola tekstowego wyszukiwania/filtru
Podsumowanie
To była dość prosta implementacja, ale ponieważ masz dostęp do każdego elementu, w tym przypadku klasy User, możesz wykonać dowolny rodzaj niestandardowego filtrowania. ponieważ masz dostęp do wszystkich danych o każdym elemencie na liście. Na przykład powyższy przykład można łatwo zmienić na filtrowanie według wieku, patrząc na właściwość Age zamiast właściwości Name, lub można zmodyfikować go tak, aby patrzył na więcej niż jedną właściwość, np. aby odfiltrować użytkowników z wiekiem poniżej X ORAZ nazwą, która nie zawiera "Y".