简体   繁体   中英

Get ListBox SelectedItems

I feel like this should be a simple feature but I don't know how to bind to the selected items in a Listbox without using code behind.

I have a Listbox with Datatemplate containing a Checkbox. I want to get the list of the checked/selected items. How do I do this?

If I cannot get the SelectedItems, I want to bind to something that triggers "SelectedProduct" every time something gets selected so I can iterate through the "ProductList" and find the checked items. However, SelectedItem does not trigger every time I click on an item.

Here is my code:

<ListBox ItemsSource="{Binding ProductList}" SelectedItem="{Binding SelectedProduct}" SelectionMode="Multiple">
<ListBox.ItemTemplate>
    <DataTemplate>
        <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding ID}" Margin="2"/>
    </DataTemplate>
</ListBox.ItemTemplate>

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsChecked}"/>
    </Style>
</ListBox.ItemContainerStyle>

A normal rational person would think SelectedItems should be bindable. Except... it isn't. And that sucks .

You have already hit on the usual approach, bind IsSelected to a property in your data object, then do something like:

myCollection.Where(i => i.Selected);

According to MSDN SelectedItem can return any selected item if the mode is set to "Multiple", so its trigger timing semantics are going to be undefined at best. Getting a notification when any part of the selection changes is going to be tricky, but you can always run logic when the Selected property gets changed (for example, raise an event the VM listens for).

You can use Interactivity extension:

Add the reference to System.Windows.Interactivity.dll using reference wizard, search in Extensions section.

Then include the following namespace in your xaml:

 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

And you can do this:

<ListBox x:Name="FooList">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged" >
            <i:InvokeCommandAction Command="{Binding FooCommand}" CommandParameter="{Binding SelectedItems, ElementName=FooList}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListBox>

In your ViewModel create a ICommand that get the current selected items.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM