Multiple selection in WPF MVVM ListBox

15,387

You can use this code for MVVM Pattern

XAML

<ListBox x:Name="DeleteHistoryListBoxItem" SelectedItem="{Binding Path=DeleteHistorySelectedItem,UpdateSourceTrigger=PropertyChanged}" 
         ItemsSource="{Binding DeleteHistoryListBox, NotifyOnSourceUpdated=True}" SelectionMode="Multiple">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Item}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

ViewModel

private ObservableCollection<HistoryItems> deleteHistoryListBox = new ObservableCollection<HistoryItems>();
public ObservableCollection<HistoryItems> DeleteHistoryListBox
{
    get
    {
        return deleteHistoryListBox;
    }
    set
    {
        deleteHistoryListBox = value;
        this.RaisePropertyChanged("DeleteHistoryListBox");
    }
}

private HistoryItems deleteHistorySelectedItem;
public HistoryItems DeleteHistorySelectedItem
{
    get
    {
        return deleteHistorySelectedItem;
    }
    set
    {
        var selectedItems = DeleteHistoryListBox.Where(x => x.IsSelected).Count();
        this.RaisePropertyChanged("DeleteHistorySelectedItem");
    }
}

Class

public class HistoryItems : INotifyPropertyChanged
{
    private string item;

    public string Item
    {
        get { return item; }
        set
        {
            item = value;
            this.RaisePropertyChanged("Item");
        }
    }

    private bool isSelected;

    public bool IsSelected
    {
        get { return isSelected; }
        set
        {
            isSelected = value;
            this.RaisePropertyChanged("IsSelected");
        }
    }
}
Share:
15,387
Michal
Author by

Michal

Updated on June 14, 2022

Comments

  • Michal
    Michal almost 2 years

    I have a ListBox containing filenames. Now I need to get array of selected items from this ListBox. I found a few answers here, but none of them worked for me. I'am using Caliburn Micro framework.

    Here is my View:

    <Window x:Class="ProgramsAndUpdatesDesktop.Views.DeleteHistoryView"
        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:local="clr-namespace:ProgramsAndUpdatesDesktop.Views"
        mc:Ignorable="d"
        ResizeMode="CanResizeWithGrip"
        MaxWidth="300"
        MinWidth="300"
        MinHeight="500"
        Title="DeleteHistoryView" Height="500" Width="300">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="30" />
        </Grid.RowDefinitions>
        <StackPanel Grid.Column="0" Grid.Row="0">
            <ListBox x:Name="DeleteHistoryListBox" SelectedItem="{Binding Path=DeleteHistorySelectedItem}" 
                     ItemsSource="{Binding DeleteHistoryListBox, NotifyOnSourceUpdated=True}" 
                 SelectionMode="Multiple">
            </ListBox>
        </StackPanel>
        <StackPanel Grid.Column="0" Grid.Row="1">
            <Button x:Name="DeleteHistoryButtonAction">Delete</Button>
        </StackPanel>
    </Grid>
    

    And here is my ViewModel:

    class DeleteHistoryViewModel : Screen
    {
        string historyFolderPath = Environment.ExpandEnvironmentVariables(ConfigurationManager.AppSettings["HistoryFolderPath"]);
    
        private ObservableCollection<string> deleteHistoryListBox = new ObservableCollection<string>();
        public ObservableCollection<string> DeleteHistoryListBox
        {
            get { return deleteHistoryListBox; }
            set { deleteHistoryListBox = value; NotifyOfPropertyChange(() => DeleteHistoryListBox); }
        }
    
        private List<string> deleteHistorySelectedItem = new List<string>();
        public List<string> DeleteHistorySelectedItem
        {
            get { return deleteHistorySelectedItem; }
            set { deleteHistorySelectedItem = value; }
        }
    
        public DeleteHistoryViewModel()
        {
            base.DisplayName = "Delete History";
        }
    
        protected override void OnInitialize()
        {
            FillListBox();
        }
    
        private void FillListBox()
        {
            string[] directory = Directory.GetFiles($"{historyFolderPath}\\", "*.json");
    
            foreach (var item in directory)
            {
                string fileName = System.IO.Path.GetFileName(item).ToString();
                if (!DeleteHistoryListBox.Contains(fileName))
                {
                    DeleteHistoryListBox.Add(fileName);
                }
            }
        }
    
        #region ACTIONS REGION
    
        // DELETE HISTORY ACTION
        public void DeleteHistoryButtonAction()
        {
            foreach (var item in DeleteHistorySelectedItem)
            {
                MessageBox.Show(item);
            }
        }
    
        #endregion
    
    }