Add a way for SelectedItemsControl to keep the selected item even if it isn't present in the ItemsSource
Is your feature request related to a problem? Please describe.
Currently, as soon as SelectedItemsControl doesn't contain its SelectedItem/SelectedIndex/SelectedValue anymore, the selection is reset.
While we have various workarounds present to prevent selection from being changed too aggressively at init time (such as #18634), scenarios exist where it makes sense to have the selection uncorrelated from the items, notably for ComboBox.
For example, a common scenario is to have the ItemsSource loaded later. It could be on demand when the ComboBox opens, or loaded in chunks if the source is too large.
Describe the solution you'd like
A new property should be added to keep the existing selection, until the user explicitly interacts with it through the SelectingItemsControl.
Proposed names:
KeepsSelectionAllowSelectionOutsideItemsAutoResetSelection(reverse behavior,trueby default)
Describe alternatives you've considered
No response
Additional context
#18147, #18323 and probably others I can't find right now.
Summary of a quick discussion with @MrJul:
- This is not intended only for init-time and
DataContext-changed-time (as the linked issues refer to) - hence it adding a public property to the API. One proposed use-case is for a lazy-loading list where one wants to be able to set the selected item before the list has completely loaded. - It's unclear how
SelectedIndexwould work here: how do we signal "we have a selection, but we don't know its index"? Probably just returning-1fromSelectedIndexwould suffice but does this make the API confusing in that settingKeepsSelectionwould makeSelectedItemandSelectedIndexno longer match?
I'm writing a lot of cascading filters recently (each stage's selection and overall state is used to populate the next stage's options) and the issue of resetting selections to null is brutal. I'm heavily considering reimplementing a simplified SelectingItemsControl because it may be more maintainable.
I'm using pretty much every other tool in my toolbox - R3 to curb reentrancy, equatable lists to preserve the existing ItemsSource when a new version is populated but hasn't changed, ensuring that the selection comes from within the collection, etc to prevent infighting from selection controls that think they know better. It's still not quite enough. I hope this kind of improvement can make it into v12.
Summary of a quick discussion with @MrJul: does this make the API confusing in that setting
KeepsSelectionwould makeSelectedItemandSelectedIndexno longer match?
While it is true this can be confusing, isn't current behavior is even more confusing?
Currently ComboBox (for example) can change SelectedItem to null even if property in DataContext didn't change, simply because Reset event for observable collection was fired due to update, even if item is still within the collection
Please consider this behavior with async architecture when your collection can be updated from different triggers (user opened page, background worker, user clicked update button, or any of them combined) this oftenly leads to unpredictable behavior, with UI corrupting actual model data, which in my opinion is much worse, than SelectedIndex not matching SelectedItem :)