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.
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :