Je souhaitais vous faire profiter d'une petite méthode utilitaire que j'ai réalisé cette semaine pour me faciliter la vie dans mes projets.

Si comme moi vous utilisez LINQ régulièrement et que vous l'utilisez dans le cadre de projet WPF, vous aimeriez bien pouvoir transformer le produit d'une requête LINQ en une ObservableCollection, et cela, afin de faciliter le databinding (bidirectionnelle).

Ainsi, si on observe la variable users crée comme suit :

var users = from u in UserManager.GetUsers()

where u.Age >= 18

select u;

Nous aimerions bien la lier avec une ListBox à l'aide d'une ObservableCollection comme suit :

lstUser.DataContext = users.ToObservableCollection<User>();

Techniquement, il s'agit donc de transformer une collection IEnumerable<T> (résultat de la requête LINQ) en ObservableCollection <T> pour cela, je vous propose une méthode d'extension dont le code source est le suivant :

public static class ObservableCollectionTools

{

public static ObservableCollection<TSource> ToObservableCollection<TSource>(this IEnumerable<TSource> source)

{

ObservableCollection<TSource> target = new ObservableCollection<TSource>();

using (IEnumerator<TSource> enumerator = source.GetEnumerator())

{

while (enumerator.MoveNext())

{

target.Add(enumerator.Current);

}

}

return target;

}

}

Cela facilite donc notre travail nous permettant de réaliser facilement le Databinding entre une ListBox et le résultat d'une requête LINQ.

Une fois la méthode précédente insérée dans vos projets, l'utilisation est simple comme le montre le print screen suivant :

 

Solution complète

Afin de vous présenter une mise en œuvre complète, voici un exemple, qui affiche des users à partir d'une requête LINQ, en utilisant notre méthode d'extension :

Tout d'abord le code de la fenêtre WPF qui comporte la ListBox et un DataTemplate permettant d'afficher des users (Nom, prénom, âge)

< Window x : Class ="WpfExtensionObservableCollection.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:WpfExtensionObservableCollection"

Title="Window1" Height="391" Width="510"

Loaded="Window_Loaded">

< Window.Resources >

< DataTemplate x : Key ="dtUser" DataType ="{ x : Type local : User }">

< StackPanel Orientation ="Vertical">

< TextBlock Text ="{ Binding Path =Name}" />

< TextBlock Text ="{ Binding Path =Surname}" />

< TextBlock Text ="{ Binding Path =Age}" />

</ StackPanel >

</ DataTemplate >

</ Window.Resources >

< Grid >

< StackPanel Grid.Column ="0" Orientation ="Vertical">

< ListBox x : Name ="lstUser" ItemsSource ="{ Binding }" ItemTemplate ="{ StaticResource dtUser }" Background ="Black" Foreground ="White"></ ListBox >

</ StackPanel >

</ Grid >

</ Window >

 

Il nous faut, de plus, une classe métier « User » et son manager « UserManager » pour nous exposer tous les users disponibles.

 

public class User

{

public string Name { get; set; }

public string Surname { get; set; }

public int Age { get; set; }

 

public User(string name, string surname, int age)

{

this.Age = age;

this.Name = name;

this.Surname = surname;

}

}

 

public class UserManager

{

public static List<User> GetUsers()

{

List<User> liste = new List<User>();

liste.Add(new User("Patrice", "test", 23));

liste.Add(new User("Jean-pierre", "test", 28));

liste.Add(new User("Sébastien", "test", 30));

liste.Add(new User("lolo", "test", 23));

liste.Add(new User("yann", "test", 24));

liste.Add(new User("Sacha", "test", 56));

liste.Add(new User("fred", "test", 34));

liste.Add(new User("Olivier", "test", 34));

liste.Add(new User("fabien", "test", 20));

liste.Add(new User("Julien", "test", 25));

liste.Add(new User("Alain", "test", 34));

liste.Add(new User("Alex", "test", 30));

return liste;

}

}

 

 

Puis le code behind de la fenêtre Windows qui utilise la requête LINQ pour filtrer les users (ceux de moins de 32 ans) à afficher en utilisant notre méthode d'extension.

 

public partial class Window1 : Window

{

public Window1()

{

InitializeComponent();

}

 

private void Window_Loaded(object sender, RoutedEventArgs e)

{

var users = from u in UserManager.GetUsers()

where u.Age < 32

select u;

 

lstUser.DataContext = users.ToObservableCollection<User>();

}

}

 

Le résultat, à l'exécution :

 

Hope to help you…

 

Musashi.