0

I have to create a small WPF/MVVM based GUI that shows the user a list of objects that I get from an external library. The user cannot directly edit those objects, but only select them for further usage. At first I though I could directly use the given objects in a regular collection as I did not see any need for an INotifyPropertyChanged implementation, but then I noticed that I would need an IsSelected property so that the view model would know which objects are selected by the user and furthermore there is also one case where I have to select specific objects from the view model. This means I have to somehow add the said IsSelected property to make this scenario work in MVVM.

What options do I have?

Do I have to write a wrapper class that inherits from the external class and only extends it by the said IsSelected Property? This would mean I would also have to convert the list of objects that I get from the external library before I can use them.

Or is there maybe a more convenient way to extend the external object so that I can handle the selection in an MVVM based way?

Ralf
  • 293
  • 5
  • 15
  • 3
    You may not even need the IsSelected property when you bind a control that supports multiple selection, e.g. a ListBox, to a collection of your objects. ListBox has a SelectedItems property which contains all items from the source collection that are currently selected. Set SelectionMode to Multiple or Extended. – Clemens Aug 23 '18 at 08:46
  • The "more convenient way" would be to create a new partial class that simply adds the IsSelected property but this would require you to define the class in the same namespace and assembly as the original type. If you can't do this, creating a wrapper class is a good choice actually. Binding to non-client aware domain objects is rarely a good idea. – mm8 Aug 23 '18 at 15:16

1 Answers1

1

You can define a collection of the selected objects on your viewmodel, like:

public class YourViewModel
{
    public List<Thing> SelectedThings { get; } = new List<Thing>();
}

Because the SelectedItems property of the built-in WPF ListBox is not a DependencyProperty so it cannot be bound, you can manage your collection with a simple event handler like

<ListBox SelectionChanged="ListBox_SelectionChanged" />

in codebehind:

private YourViewModel vm;

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    foreach (var item in e.AddedItems)
    {
        vm.SelectedThings.Add(item);
    }
    foreach (var item in e.RemovedItems)
    {
        vm.SelectedThings.Remove(item);
    }
}

If you want to set the selected items from the view model, too, I have found a good solution instead of event handler here: https://www.tyrrrz.me/Blog/WPF-ListBox-SelectedItems-TwoWay-binding

Clemens
  • 123,504
  • 12
  • 155
  • 268
lvoros
  • 312
  • 1
  • 14
  • you're right. I haven't used the default WPF ListBox since ages... I've found a solution here: https://stackoverflow.com/a/46406642/6255303 – lvoros Aug 23 '18 at 11:09
  • or look at this: https://www.tyrrrz.me/Blog/WPF-ListBox-SelectedItems-TwoWay-binding – lvoros Aug 23 '18 at 11:12
  • Unfortunately Clemens did not write an answer but only a comment. However he pointed me to the right direction: Using the SelectedItems property of the ListView. I quickly noticed that this property is not available by default in XAML, but there are many solutions out there using code behind or even pure MVVM. I decided for this one: https://stackoverflow.com/questions/31176949/binding-selecteditems-of-listview-to-viewmodel – Ralf Aug 23 '18 at 15:27