Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to support ListBox SelectedItems binding with MVVM in a navigable application

Tags:

c#

mvvm

wpf

listbox

I am making a WPF application that is navigable via custom "Next" and "Back" buttons and commands (i.e. not using a NavigationWindow). On one screen, I have a ListBox that has to support multiple selections (using the Extended mode). I have a view model for this screen and store the selected items as a property, since they need to be maintained.

However, I am aware that the SelectedItems property of a ListBox is read-only. I have been trying to work around the issue using this solution here, but I have not been able to adopt it into my implementation. I found that I can't differentiate between when one or more elements are deselected and when I navigate between screens (NotifyCollectionChangedAction.Remove is raised in both cases, since technically all the selected items are deselected when navigating away from the screen). My navigation commands are located in a separate view model which manages the view models for each screen, so I can't put any implementation related to the view model with the ListBox in there.

I have found several other less elegant solutions, but none of these seem to enforce a two-way binding between the view model and the view.

Any help would be greatly appreciated. I can provide some of my source code if it would help to understand my problem.

like image 301
caseklim Avatar asked Jun 21 '12 16:06

caseklim


2 Answers

Try creating an IsSelected property on each of your data items and binding ListBoxItem.IsSelected to that property

<Style TargetType="{x:Type ListBoxItem}">     <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> </Style> 
like image 75
Rachel Avatar answered Oct 17 '22 19:10

Rachel


Rachel's solutions works great! But there is one problem I've encountered - if you override the style of ListBoxItem, you loose the original styling applied to it (in my case responsible for highlighting the selected item etc.). You can avoid this by inheriting from the original style:

<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">     <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> </Style> 

Note setting BasedOn (see this answer) .

like image 44
Mifeet Avatar answered Oct 17 '22 20:10

Mifeet