0
votes

I have a ListView of items, and I want to run some code every time the user selects or deselects an item without resorting to event handlers in the control's codebehind - everything is being done in the view the control has its datacontext set to.

When the ListView's selection mode is "Single" I can simply bind "SelectedItem" to a property in my view, and watch for when that property's change event. If selection mode is "Multiple" however, the behaviour is completely unreliable. Sometimes the last item clicked changes the SelectedItem, and sometimes it doesn't. This DependencyProperty appears to be complete trash when the selection mode isn't single. How else can I use a binding to track changes to the ListView's SelectedItems collection?

Note that I don't use Expression blend so I won't be using Interaction.Triggers or similar library solutions.

<ListView ItemsSource="{Binding Path=Zones}"  
          SelectionMode="Multiple"
          SelectedItem="{Binding SelectedZone}">
2
don't really understand this sentence: "without resorting to event handlers in the control's codebehind ". So how do you want to make a DataBinding if not relaying on something in code-behind?? - Tigran
@Tigran In WPF, xaml files (UI) have a codebehind which can contain program logic and event handlers for its controls such as the ListView.SelectionChanged event. There's something called the MVVM pattern which involves using datacontexts and bindings such that the control can be bound to an object model directly rather than using intermediary methods that manipulate properties programatically. Because my control is bound to its underlying data in that way, it is a huge pain (and inelegant) to then split the work done on this underlying data between the view and the codebehind of the control. - Alain
Try turning virtualiztion off on the ListView. Are you seeing that when you click an item that is on the same screen as the currently selected item you get a different result than if you had to scroll down to the item. This sounds strange but what I would try is make the ListView single but make the items themselves toggleable (just a bool property isManuallySelected) and a custom presentation in XAML based on isManuallySelected so it looks and feels like a multiselect. - paparazzo
@BalamBalam Interesting suggestion, but in my case it can't possibly be the cause - my ListView is stretched to show all items, which is usually less than 10. The items themselves are togglable (they are DataRowViews, and the first column is a boolean bound to a checkbox in the listview), but I was under the impression that you could put a property watch on individual cells in a DataTable. It would be a much simpler problem if the items in the collection had their own object model, then I could just add a bound 'isSelected' property to it and watch that. - Alain
If you have less than 10 rows then turning off virtualization is not going to hurt. Did you try it? You have a ListView GridView? I would create an ObservableCollection before I tried to automate a DataTable everytime. - paparazzo

2 Answers

0
votes

Don't see any other way then described in this good article.

The thing is, that unfrotunately, SelectedItems property is readonly, so can not be databinded.

Till now it's kind of tricky story, unfortunately.

0
votes

The only solution was to wrap the ItemsTemplate for the list in a control that can be toggled and has a command binding (like a button) and then bind the viewmodel to that command binding. It's a huge pain and requires hacking around with the HitTestVisibility and binding the button's state to the item's selected state, but it works in the end.