Вот еще одно решение. Это похоже на ответ Бена , но привязка работает двумя способами. Хитрость заключается в обновлении выбранных элементов ListBox
при изменении связанных элементов данных.
public class MultipleSelectionListBox : ListBox
{
public static readonly DependencyProperty BindableSelectedItemsProperty =
DependencyProperty.Register("BindableSelectedItems",
typeof(IEnumerable), typeof(MultipleSelectionListBox),
new FrameworkPropertyMetadata(default(IEnumerable),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnBindableSelectedItemsChanged));
public IEnumerable BindableSelectedItems
{
get => (IEnumerable)GetValue(BindableSelectedItemsProperty);
set => SetValue(BindableSelectedItemsProperty, value);
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
BindableSelectedItems = SelectedItems.Cast();
}
private static void OnBindableSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is MultipleSelectionListBox listBox)
listBox.SetSelectedItems(listBox.BindableSelectedItems);
}
}
К сожалению, я не смог использовать IList
в качестве типа BindableSelectedItems. Это отправлено null
в свойство моей модели представления, тип которого IEnumerable
.
Вот XAML:
Есть одна вещь, о которой следует помнить. В моем случае из представления можно удалить ListBox
. По какой-то причине это приводит к тому, что свойство SelectedItems
изменяется на пустой список. Это, в свою очередь, приводит к изменению свойства модели представления в пустой список. В зависимости от вашего варианта использования это может быть нежелательно.