Reputation: 41
What is the situation:
I'm working on a C# WPF application with Caliburn.Micro. I am using the MVVM pattern.
I have a ListView with a ContentControl as ItemTemplate. The ListView's ItemsSource is bound to a List (ObservableCollection) of ViewModels in the corresponding ViewModel.
<ListView ItemsSource="{Binding ViewModelList}" SelectionMode="Extended">
<ListView.ItemTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
What I want:
I want to get the selected items (all of them) of the ListView, but I don't know how without violating the MVVM pattern.
It would be nice to have a property "IsSelected" in the ViewModels that are presented by the ContentControl and to bind that somehow to my ListView.
Is it possible to do that or is there another/a better way?
Update:
It was easier than expected. I added a property public bool IsSelected { get; set; }
in my ViewModel and put this inside the ListView Control:
<UserControl.Resources>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListViewItem}}">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</UserControl.Resources>
Now I can get the selected items with:
foreach (var item in ViewModelList)
{
if (item.IsSelected)
{
// Do stuff
}
}
Upvotes: 2
Views: 3744
Reputation: 4464
This is probably the code you're looking for. If you're using a multiple selection list view, you could get all the selected items with below code.
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectionChanged}" CommandParameter="{Binding Path=SelectedItems, ElementName=ListViewName}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Bind it to a command in the viewmodel.
private ICommand selectionChanged;
public ICommand SelectionChanged
{
get { return selectionChanged; }
set { SetProperty(ref selectionChanged, value); }
}
Upvotes: 1
Reputation: 203
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=OneWayToSource}"/>
</Style>
</Grid.Resources>
<ListView ItemsSource="{Binding ViewModelList}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding IsSelected}"/>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal">
</StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
Upvotes: 1