I want to select programatically multiple items in my ListBox. So, to be as mvvm friendly as possible, I create a custom control inherited from ListBox. In this custom control I've made a dependency property allowing items selection changes. Here is the code of the OnPropertyChanged part :
private static void OnSetSelectionToPropertyChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
InitializableListBox list = d as InitializableListBox;
Dictionary<int, string> toSelect = e.NewValue as Dictionary<int, string>;
if (toSelect == null)
return;
list.SetSelectedItems(toSelect);
}
The selection works great, but this solution does not raise the OnSelectionChanged
event
So I try also :
private static void OnSetSelectionToPropertyChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
InitializableListBox list = d as InitializableListBox;
Dictionary<int, string> toSelect = e.NewValue as Dictionary<int, string>;
if (toSelect == null)
return;
SelectionChangedEventArgs e_selChanged;
List<Object> removed = new List<object>();
List<Object> added = new List<object>();
//Clear the SelectedItems list
while(list.SelectedItems.Count > 0)
{
removed.Add(list.SelectedItems[0]);
list.SelectedItems.RemoveAt(0);
}
//Add each selected items
foreach (var item in toSelect)
{
list.SelectedItems.Add(item);
added.Add(list.SelectedItems[list.SelectedItems.Count - 1]);
}
//Raise the SelectionChanged event
e_selChanged = new SelectionChangedEventArgs(SelectionChangedEvent,removed,added);
list.OnSelectionChanged(e_selChanged);
}
But this was not better. I think I'm not dealing the right way with the event so if you could help me, that would be great.
Thanks in advance.
EDIT
I have found another solution (more a hack actually) than @NETscape. I don't think it's better, but it seems to work pretty well, and it's maybe easier.
The trick is to made a dependency property wich allow you to access the SelectedItems
property (wich is readonly and unbindable on the normal ListBox
). Here is the code of my custom ListBox :
public class InitializableListBox : ListBox
{
public InitializableListBox()
{
SelectionChanged += CustomSelectionChanged;
}
private void CustomSelectionChanged(object sender, SelectionChangedEventArgs e)
{
InitializableListBox s = sender as InitializableListBox;
if (s == null)
return;
s.CustomSelectedItems = s.SelectedItems;
}
#region CustomSelectedItems DependyProperty
public static DependencyProperty CustomSelectedItemsProperty =
DependencyProperty.RegisterAttached("CustomSelectedItems",
typeof(System.Collections.IList),typeof(InitializableListBox),
new PropertyMetadata(null, OnCustomSelectedItemsPropertyChanged));
public System.Collections.IList CustomSelectedItems
{
get
{
return (System.Collections.IList)GetValue(CustomSelectedItemsProperty);
}
set
{
SetValue(CustomSelectedItemsProperty, value);
}
}
private static void OnCustomSelectedItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
InitializableListBox list = d as InitializableListBox;
System.Collections.IList toSelect = e.NewValue as System.Collections.IList;
if (toSelect == null)
return;
list.SetSelectedItems(toSelect);
}
#endregion
}