mash
mash

Reputation: 41

Get the selected items of a ListView (MVVM, Caliburn.Micro)

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

Answers (2)

ViVi
ViVi

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

M312V
M312V

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

Related Questions