Mr.B
Mr.B

Reputation: 3787

prism 5.0 InvokeCommandAction SelectionMode="Multiple"

I want to detect all selected items in List Box through InvokeCommandAction prism 5.0.

XAML:

<Window x:Class="Selection.Prism5._0.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:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:local="clr-namespace:Selection.Prism5"
    xmlns:prism="http://www.codeplex.com/prism"
    mc:Ignorable="d"
    Title="MainWindow"
    Height="350"
    Width="525">
<FrameworkElement.DataContext>
    <local:MainViewModel />
</FrameworkElement.DataContext>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="5" />
        <ColumnDefinition Width="3*" />
    </Grid.ColumnDefinitions>
    <ListBox SelectedItem="{Binding SelectedItem}"
             ItemsSource="{Binding Items}"
             SelectionMode="Multiple">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <prism:InvokeCommandAction Command="{Binding SelectItemsCommand}"
                                           TriggerParameterPath="AddedItems" />
            </i:EventTrigger>
        </i:Interaction.Triggers>

        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

</Grid>

View Model:

  public class MainViewModel : BindableBase
{
    public MainViewModel()
    {
        this.Items = new List<Model>
        {
           new Model {Id=1,Name="Name 1" },
           new Model {Id=2,Name="Name 2" },
           new Model {Id=3,Name="Name 3" },
           new Model {Id=4,Name="Name 4" },
           new Model {Id=5,Name="Name 5" },
           new Model {Id=6,Name="Name 6" }
        };
        SelectItemsCommand = new DelegateCommand<object[]>((items) =>
        {
            if (items != null && items.Count() > 0)
            {
                SelectedItems = items.Select(i => (Model)i);
            }
        });

    }



    public ICommand SelectItemsCommand { get; private set; }

    private IEnumerable<Model> _items;
    public IEnumerable<Model> Items
    {
        get { return _items; }
        set
        {
            _items = value; base.OnPropertyChanged("Items");
        }
    }


    private IEnumerable<Model> _selectedItems;
    public IEnumerable<Model> SelectedItems
    {
        get { return _selectedItems; }
        set
        {
            _selectedItems = value; base.OnPropertyChanged("SelectedItems");
        }
    }
    private Model _selectedItem;
    public Model SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            _selectedItem = value; base.OnPropertyChanged("SelectedItem");
        }
    }
}

It should work, however it doesn't. When I select more than one item in GUI:

enter image description here

View model code recognizes only one item:

enter image description here

I saw this example in "What's New in Prism 5.0" by Brian Lagunas and as far as I understood, this technic may be used for multi-selection too. What have I done wrong here?

Upvotes: 0

Views: 1507

Answers (2)

Suresh
Suresh

Reputation: 71

SelectionChangedEventArgs.AddedItems gives you the selection list of a particular action. if ListBox SelectionMode is "Multiple" or "Single" you cannot select multiple items at a single click. if ListBox SelectionMode is "Extended" you can select multiple items with the help of the shift key.

SelectionChangedEventArgs.AddedItems will not give all selected items of the list box for a particular action.

For your need,

In View,

Change TriggerParameterPath="AddedItems" to TriggerParameterPath="Source.SelectedItems" .

In ViewModel

Change DelegateCommand<object[]> to DelegateCommand<System.Collections.ICollection>

Ref: http://frststart.blogspot.com/2016/10/selectionchangedselecteditemstutorial.html

Upvotes: 1

mm8
mm8

Reputation: 169190

You are selecting one item at a time and the command is invoked for each time you select an item.

This is the expected behaviour.

If you want to keep track of the currently selected items you could add an IsSelected property to the Model class and use an ItemContainerStyle to bind this one to the IsSelected property of the ListBoxItem container:

<ListBox SelectedItem="{Binding SelectedItem}"
             ItemsSource="{Binding Items}"
             SelectionMode="Multiple">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <prism:InvokeCommandAction Command="{Binding SelectItemsCommand}"
                                           TriggerParameterPath="AddedItems" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

SelectItemsCommand = new DelegateCommand<System.Collections.IList>((items) =>
{
    SelectedItems = Items.Where(x => x.IsSelected).ToList();
});

Upvotes: 0

Related Questions