You can create a List AttachedProperty for a ListBox that adds items to the ListBox.SelectedItems when the list changes.
AttachedProperty solution keeps WPF clean and your MVVM template, also makes this function multiple for all your projects :)
Here is an example:
AttachedProperty:
public static class ListBoxExtensions { // Using a DependencyProperty as the backing store for SearchValue. This enables animation, styling, binding, etc... public static readonly DependencyProperty SelectedItemListProperty = DependencyProperty.RegisterAttached("SelectedItemList", typeof(IList), typeof(ListBoxExtensions), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemListChanged))); public static IList GetSelectedItemList(DependencyObject obj) { return (IList)obj.GetValue(SelectedItemListProperty); } public static void SetSelectedItemList(DependencyObject obj, IList value) { obj.SetValue(SelectedItemListProperty, value); } private static void OnSelectedItemListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var listbox = d as ListBox; if (listbox != null) { listbox.SelectedItems.Clear(); var selectedItems = e.NewValue as IList; if (selectedItems != null) { foreach (var item in selectedItems) { listbox.SelectedItems.Add(item); } } } } }
Using Xaml:
<ListBox ItemsSource="{Binding Items}" SelectionMode="Multiple" local:ListBoxExtensions.SelectedItemList="{Binding SelectedItems}" />
Demo:
Working example if you want to test:
Xaml:
<Window x:Class="WpfApplication17.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication17" Title="MainWindow" Height="227" Width="170" Name="UI"> <Grid DataContext="{Binding ElementName=UI}"> <ListBox ItemsSource="{Binding Items}" SelectionMode="Multiple" local:ListBoxExtensions.SelectedItemList="{Binding SelectedItems}" Margin="0,0,0,37" > <ListBox.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{x:Static SystemColors.HighlightColor}" /> <Style TargetType="ListBoxItem"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/> </Trigger> </Style.Triggers> </Style> </ListBox.Resources> </ListBox> <Button Content="Populate SelectedItemList" Click="Button_Click" Height="32" Margin="2,0,1,2" VerticalAlignment="Bottom"/> </Grid> </Window>
code:
namespace WpfApplication17 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window, INotifyPropertyChanged { private List<string> _selectedItems = new List<string>(); private ObservableCollection<string> _items = new ObservableCollection<string> { "Orange", "Mango", "Stawberry", "Pineapple", "Apple", "Grape", "Banana" }; public MainWindow() { InitializeComponent(); } public ObservableCollection<string> Items { get { return _items; } set { _items = value; } } public List<string> SelectedItems { get { return _selectedItems; } set { _selectedItems = value; OnPropertyChanged("SelectedItems"); } } private void Button_Click(object sender, RoutedEventArgs e) { SelectedItems = new List<string> { "Orange", "Pineapple", "Apple" }; } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string e) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(e)); } } public static class ListBoxExtensions { // Using a DependencyProperty as the backing store for SearchValue. This enables animation, styling, binding, etc... public static readonly DependencyProperty SelectedItemListProperty = DependencyProperty.RegisterAttached("SelectedItemList", typeof(IList), typeof(ListBoxExtensions), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemListChanged))); public static IList GetSelectedItemList(DependencyObject obj) { return (IList)obj.GetValue(SelectedItemListProperty); } public static void SetSelectedItemList(DependencyObject obj, IList value) { obj.SetValue(SelectedItemListProperty, value); } private static void OnSelectedItemListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var listbox = d as ListBox; if (listbox != null) { listbox.SelectedItems.Clear(); var selectedItems = e.NewValue as IList; if (selectedItems != null) { foreach (var item in selectedItems) { listbox.SelectedItems.Add(item); } } } } } }
Result:
