0

I am working with Listbox in wpf.My problem is I am getting only one selected item from listbox.I want to get all the item which is selected but don't know how to implement ? please help! Here is my code :

<ListBox ItemsSource="{Binding Markets}" BorderThickness="0" Background="{x:Null}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionMode="Multiple" SelectedItem="{Binding SelectedItem}">
     <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel IsItemsHost="True" />
            </ItemsPanelTemplate>
     </ListBox.ItemsPanel>
     <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding}" Style="{DynamicResource CheckBoxStyle1}" Width="140" Margin="10"/>
            </DataTemplate>
     </ListBox.ItemTemplate>
</ListBox>

This is my viewmodel content:

    private string _selectedItem;
    public List<string> Markets { get; set;}
    public SettingVM()
    {

        Markets = new List<string>();
        Markets.Add("United Kingdom");
        Markets.Add("Australia");
    }
    public string SelectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
            Set(() => SelectedItem, ref _selectedItem, value);
        }
    }     
Dhruv Gohil
  • 842
  • 11
  • 34

5 Answers5

1

You can bind directly the SelectedItem listobx property to your view model but not the SelectedItems property.

I used a behavior to achieve this associated with a delegate command (included in the Prism framework)

Your object

class MyObject
{

}

The behavior

internal class MyObjectSelectionChangedToCommand
{

    public static readonly DependencyProperty SelectionCommandProperty =
        DependencyProperty.RegisterAttached("SelectionCommand", typeof(DelegateCommand<GridSelectionInfo<MyObject>>),
        typeof(ResourceCardGridSelectionChangedToCommand), new PropertyMetadata(null, OnSelectionCommandChanged));

    public static DelegateCommand<GridSelectionInfo<MyObject>> GetSelectionCommand(DependencyObject obj)
    {
        return (DelegateCommand<GridSelectionInfo<MyObject>>)obj.GetValue(SelectionCommandProperty);
    }

    public static void SetSelectionCommand(DependencyObject obj, DelegateCommand<GridSelectionInfo<MyObject>> value)
    {
        obj.SetValue(SelectionCommandProperty, value);
    }

    private static void dg_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var tsci = new GridSelectionInfo<MyObject>
        {
            Added = e.AddedItems.Cast<MyObject>().ToList(),
            Removed = e.RemovedItems.Cast<MyObject>().ToList(),
            Selected = ((ListBox)sender).SelectedItems.Cast<MyObject>().ToList()
        };

        var cmd = GetSelectionCommand((DependencyObject)sender);
        cmd.Execute(tsci);
    }

    private static void OnSelectionCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var dg = d as ListBox;

        if (dg != null) dg.SelectionChanged += dg_SelectionChanged;
    }
}

public class GridSelectionInfo<T>
{
    public GridSelectionInfo()
    {
        Selected = new List<T>();
        Added = new List<T>();
        Removed = new List<T>();
    }

    public List<T> Added { get; set; }

    public List<T> Removed { get; set; }
    public List<T> Selected { get; set; }

    public override string ToString()
    {
        return string.Format("Added: {0}, Removed: {1}, Selected: {2}", Added.Count, Removed.Count, Selected.ToFormattedString());
    }
}

The XAML part where you bind the view model command to the behavior

<ListBox  ItemsSource="{Binding MyCollection}"
 resources:ResourceCardGridSelectionChangedToCommand.SelectionCommand="{Binding CmdObjectSelectionChanged}">
</ListBox>

Then, in you view model you just have to declare the command

public DelegateCommand<GridSelectionInfo<MyObject>> CmdObjectSelectionChanged { get; private set; }

And create it

CmdObjectSelectionChanged = new DelegateCommand<<GridSelectionInfo<MyObject>>(ExecuteSelect,CanExecuteSelect);

Thus, every time the selection changes in your listbox, you will receive all the info about selected items in the execute delegate wrapped in the GridSelectionInfo object;

Bruno
  • 1,944
  • 13
  • 22
0

maybe this help you

You can find them in ListBox.SelectedItems. use foreach

foreach (ListItem li in listBox1.SelectedItems)
{
// your code here
}
Abadi
  • 112
  • 10
0

You use "SelectedItem="{Binding SelectedItem}">". Acording to MSDN "Gets or sets the first item in the current selection or returns null if the selection is empty "

And you need to bind SelectedItems to a list in your viewmodel.

Leonid Malyshev
  • 475
  • 1
  • 6
  • 14
0

In the ListBox controls, the SelectedItems property is read-only but you can add a behavior that do the job, see this answer : https://stackoverflow.com/a/8369532/1431524

Community
  • 1
  • 1
Pak
  • 2,639
  • 2
  • 21
  • 27
0

I had the same problem and when I was binding to the SelectedItems the property was not notifying the model in some cases! I ended extending my entity with a non persisted property ("Selected") and then binded this property to the IsCheched property of the CheckBox. In your case create another partial class file Market to extend the Market object, add a new bool property (e.g. Selected) and then at your checkbox bind this property:

<CheckBox Content="{Binding}" IsChecked="{Binding Selected}" Style="{DynamicResource CheckBoxStyle1}" Width="140" Margin="10"/>