I have a WPF ListView control, ItemsSource is set to an ICollectionView created this way:
var collectionView =
System.Windows.Data.CollectionViewSource.GetDefaultView(observableCollection);
this.listView1.ItemsSource = collectionView;
...where observableCollection is an ObservableCollection of a complex type. The ListView is configured to display, for each item, just one string property on the complex type.
The user can refresh the ListView, at which point my logic stores the "key string" for the currently selected item, re-populates the underlying observableCollection. The previous sort and filter is then applied to the collectionView. At this point I'd like to "re select" the item that had been selected before the request to refresh. The items in the observableCollection are new instances, so I compare the respective string properties and then just select one that matches. Like this:
private void SelectThisItem(string value)
{
foreach (var item in collectionView) // for the ListView in question
{
var thing = item as MyComplexType;
if (thing.StringProperty == value)
{
this.listView1.SelectedItem = thing;
return;
}
}
}
This all works. If the 4th item is selected, and the user presses F5, then the list is reconstituted and then the item with the same string property as the previous 4th item gets selected. Sometimes this is the new 4th item, sometimes not, but it provides "least astonishment behavior".
The problem comes when the user subsequently uses arrow keys to navigate through the ListView. The first up or down arrow after a refresh causes the first item in the (new) listview to be selected, regardless of which item had been selected by the previous logic. Any further arrow keys work as expected.
Why is this happening?
This pretty clearly violates the "least astonishment" rule. How can I avoid it?
EDIT
Upon further search, this seems like the same anomaly described by the unanswered
WPF ListView arrow navigation and keystroke problem , except I provide more detail.