(Article original blog de Sébastien)
J’ai été confronté récemment à un problème avec le Pattern MVVM. En faite je me suis posé la question de savoir comment il était possible de synchroniser mon ViewModel avec les éléments sélectionnés d’une Listbox (ou encore de façon plus général à la propritété « SelectedItems » d’un contrôle si elle existe) .
Après quelques recherche sur le web je suis tombé sur le blog de Marlon qui propose une idée très intéressante. En effet la solution est de passer par une simple propriété attachés qui grâce à l’événement SelectionChanged de la ListBox va alimenter une liste de mon ViewModel.
Voici la classe en question que j’ai appelé « SelectedItemsHelper » :
public static class SelectedItemsHelper
{
///
/// SelectedItems Attached Dependency Property
///
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(SelectedItemsHelper),
new FrameworkPropertyMetadata((IList)null,
new PropertyChangedCallback(OnSelectedItemsChanged)));
///
/// Gets the SelectedItems property. This dependency property
///
///
///
public static IList GetSelectedItems(DependencyObject d)
{
return (IList)d.GetValue(SelectedItemsProperty);
}
///
/// Sets the SelectedItems property. This dependency property
/// indicates ....
///
public static void SetSelectedItems(DependencyObject d, IList value)
{
d.SetValue(SelectedItemsProperty, value);
}
///
/// Handles changes to the SelectedItems property.
///
private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listBox = (ListBox)d;
ReSetSelectedItems(listBox);
listBox.SelectionChanged += delegate
{
ReSetSelectedItems(listBox);
};
}
private static void ReSetSelectedItems(ListBox listBox)
{
IList selectedItems = GetSelectedItems(listBox);
selectedItems.Clear();
if (listBox.SelectedItems != null)
{
foreach (var item in listBox.SelectedItems)
selectedItems.Add(item);
}
}
}
Dernier point, l’utilisation dans le XAML :
<ListBox ItemsSource="{Binding Personnes}" helper:SelectedItemsHelper.SelectedItems="{Binding PersonnesSelected}" SelectionMode="Extended"/>
Voilà vous pouvez ainsi récupérer dans la liste les éléments sélectionnés de la listbox.
Sébastien.
(Article original blog de Sébastien)