请参考以下示例代码。
public class MultipleSelectionListBox : ListBox
{
public static readonly DependencyProperty BindableSelectedItemsProperty =
DependencyProperty.Register("BindableSelectedItems",
typeof(IEnumerable<dynamic>), typeof(MultipleSelectionListBox),
new FrameworkPropertyMetadata(default(IEnumerable<dynamic>),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnBindableSelectedItemsChanged));
public IEnumerable<dynamic> BindableSelectedItems
{
get => (IEnumerable<dynamic>)GetValue(BindableSelectedItemsProperty);
set => SetValue(BindableSelectedItemsProperty, value);
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
BindableSelectedItems = SelectedItems.Cast<dynamic>();
}
private static void OnBindableSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is MultipleSelectionListBox listBox)
{
List<dynamic> newSelection = new List<dynamic>();
if (!string.IsNullOrWhiteSpace(listBox.SelectedValuePath))
foreach (var item in listBox.BindableSelectedItems)
{
var collectionValue = item.GetType().GetProperty(listBox.SelectedValuePath).GetValue(item, null);
foreach (var lbItem in listBox.Items)
{
if (lbItem.GetType().GetProperty(listBox.SelectedValuePath).GetValue(lbItem, null) == collectionValue)
newSelection.Add(lbItem);
}
}
else
newSelection = listBox.BindableSelectedItems as List<dynamic>;
listBox.SetSelectedItems(listBox.BindableSelectedItems);
}
}
}
视图模型:
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
//select 1 and 4 initially:
MyCollectionOfSelectedIDs = new List<dynamic> { Items[0], Items[3] };
}
public IList<DeviceChannelInfo> Items { get; } = new List<DeviceChannelInfo>()
{
new DeviceChannelInfo{ name = "1", displayName = "1", id =1 },
new DeviceChannelInfo{ name = "2", displayName = "2", id =2 },
new DeviceChannelInfo{ name = "3", displayName = "3", id =3 },
new DeviceChannelInfo{ name = "4", displayName = "4", id =4 }
};
private IEnumerable<dynamic> _mCollectionOfSelectedIDs;
public IEnumerable<dynamic> MyCollectionOfSelectedIDs
{
get { return _mCollectionOfSelectedIDs; }
set { _mCollectionOfSelectedIDs = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:MultipleSelectionListBox ItemsSource="{Binding Items}"
SelectionMode="Extended"
DisplayMemberPath="displayName"
SelectedValuePath="name"
BindableSelectedItems="{Binding MyCollectionOfSelectedIDs}" />
<TextBlock Grid.Row="1" Text="{Binding MyCollectionOfSelectedIDs.Count}" />
</Grid>
</Window>