This article has been localized into German by the community.
Filtern in ListViews
Wir haben jetzt schon verschiedene Dinge mit der ListView gemacht, z.B. gruppieren und sortieren, aber eine andere sehr nützliche Fähigkeit ist das Filtern. Natürlich könnte man einfach schon das Hinzufügen von Einträgen in die ListView limitieren, aber oft will man die ListView dynamisch zur Laufzeit filtern, oftmals basierend auf einem vom Benutzer eingegebenen Filterkriterium. Unser Glück, dass die Anzeigemechanismen der ListView auch das leicht ermöglichen, genau wie wir auch schon beim Sortieren und Gruppieren gesehen haben.
Filtern ist ziemlich einfach, daher lassen Sie uns direkt mit dem Beispiel loslegen, und danach diskutieren wir es:
<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; }
}
}
Der XAML-Anteil ist sehr einfach: Wie haben hier eine TextBox, in der der Benutzer ein Suchwort eingeben kann und ein ListView in der das Ergebnis angezeigt wird.
Im Code-behind beginnen wir mit dem Hinzufügen einiger User-Objekte zur ListView, genau wie in früheren Beispielen. Interessant wird es in den letzten beiden Zeilen des Konstruktors, wo wir einen Verweis auf die CollectionView-Instanz für den ListView erhalten und dann ein delegate der Filter-Eigenschaft zuordnen. Dieses delegate verweist auf die Funktion UserFilter, die wir unten implementiert haben. Es nimmt jedes Element als ersten (und einzigen) Parameter und gibt dann einen booleschen Wert zurück, der angibt, ob das angegebene Element in der Liste sichtbar sein soll oder nicht.
In der UserFilter()-Methode betrachten wir das TextBox-Control (txtFilter), um zu sehen, ob es Text enthält - wenn ja, verwenden wir es, um zu überprüfen, ob der Name des Benutzers (das ist die Eigenschaft, nach der wir filtern wollen) die eingegebene Zeichenkette enthält oder nicht, und geben dann je nachdem true oder false zurück. Wenn die TextBox leer ist, geben wir true zurück, da in diesem Fall alle Elemente sichtbar sein sollen.
Das Ereignis txtFilter_TextChanged ist ebenfalls wichtig. Jedes Mal, wenn sich der Text ändert, erhalten wir eine Referenz auf das View-Objekt der ListView und rufen dann die Methode Refresh() auf. Dadurch wird sichergestellt, dass das delegate des Filters jedes Mal aufgerufen wird, wenn der Benutzer den Wert des Textfeldes für die Suchzeichenfolge ändert.
Zusammenfassung
Das war eine sehr einfache Implementation, aber da man jede einzelne Information, wie hier von der "User"-Klasse ansprechen kann, kann man jede erdenkliche Art der benutzerdefinierten Filterung vornehmen. Zum Beispiel könnte man sehr einfach den Filter auf das Alter setzen, indem man auf das Alter, statt den Namen verweist. Oder man könnte auch nach mehr als einem Kriterium filtern. Man könnte besipielsweise herausfiltern welcher Nutzer jünger als X ist und dessen Name kein "Y" enthält.