TOC

This article is currently in the process of being translated into French (~99% done).

Le contrôle ListView:

ListView filtering

Nous avons déjà réalisé plusieurs opérations avec les ListView, telles que des opérations de regroupement (grouping) et de tri (sorting), mais il existe une autre fonction intéressante, à savoir le filtrage de données ( filtering). Il est bien évidemment possible de filtrer les éléments (items) avant de les ajouter à la ListView, mais il est souvent nécessaire de les filtrer de façon dynamique, lors de l'exécution du programme, en fonction de certaines informations de filtrage saisies par l'utilisateur. Heureusement pour nous, les ListView mettent à notre disposition des mécanismes de vue (view) qui nous permettent de réaliser ceci très facilement, comme nous l'avons vu avec le regroupement (grouping) et le tri (sorting).

Le filtrage des données (filtering) est en fait relativement simple, alors commençons immédiatement par un exemple que nous commenterons par la suite :

<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; }
	}
}

La partie XAML est très simple : nous avons une TextBox dans laquelle l'utilisateur peut saisir le texte à rechercher, et une ListBox qui affiche le résultat de cette recherche.

Dans la partie Code-behind, nous ajoutons tout d'abord des éléments de type User à la ListView, comme nous l'avions fait dans les exemples précédents. La partie intéressante réside dans les 2 dernières lignes du constructeur : nous obtenons tout d'abord une référence à une instance (view) deCollectionView, utilisable par la ListView, et nous assignons ensuite un délégué (delegate) sur la propriété Filter de cette instance (view). Ce délégué pointe vers la fonction UserFilter qui est implémentée juste en dessous. Cette fonction reçoit la liste des éléments (item) de la ListView comme premier (et unique) paramètre et renvoie un booléen qui indique si l'élément reçu en paramètre doit être visible dans la liste.

Dans la méthode UserFilter(), nous contrôlons la TextBox (txtFilter) afin de déterminer si elle contient du texte - et le cas échéant, nous utilisons cette TextBox pour contrôler si le nom de l'User (qui est la propriété sur laquelle nous avons décidé d'appliquer le filtre) contient ou non le texte saisi dans la TextBox, et nous renvoyons true ou false selon le cas. Si la TextBox est vide, nous renvoyons true, parce que dans ce cas nous voulons afficher tous les éléments (items).

L’événement txtFilter_TextChanged est également important. A chaque fois que le texte de la TextBox (txtFilter) change, nous obtenons une référence à l'objet Vue (View) de la ListView et lui appliquons la méthode Refresh(). De cette façon, nous sommes assurés que le délégué Filter est bien appelé à chaque fois que la valeur de la TextBox de recherche/filtre est modifiée par l'utilisateur.

Résumé

Cette implémentation est assez simple, mais comme nous avons accès à chaque élément, dans le cas présent à chaque élément de la classe User, il est possible d'effectuer toute sorte de tri personnalisé puisque nous avons accès à toutes les informations de chaque élément de la liste. Par exemple, il serait très facile de modifier l'exemple ci-dessus afin de filtrer en fonction de l'age, en utilisant le propriété Age au lieu de la propriété Name, ou bien de l'adapter afin de filtrer selon plusieurs propriétés : ainsi on pourrait entre autres filtrer les éléments de la classe user selon les critères suivants : afficher les users ayant un age inférieur à X ET un nom qui ne contient pas "Y".


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!