Reputation: 3787
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:
View model code recognizes only one item:
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
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
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