I have a ListView in a user control:
<ListView ...
ItemsSource="{Binding Path=MyItemsSource}"
SelectedItem="{Binding Path=SelectedItem}"
SelectionMode="{Binding Path=SelectionMode}"
>
<ListView.View>
<GridView>
...
</GridView>
</ListView.View>
</ListView>
I have code in the viewmodel to programmatically set the SelectedItem of the ListView. This is achieved by setting the SelectedItem property in the viewmodel.
I have found that when my code sets the SelectedItem property to a particular list item, the item that has keyboard focus is not changed along with it. If I change the SelectedItem property and then press the up arrow key, the newly-selected item is the one that is above the item that was selected before (because that item still has the focus), not the item above the newly-selected item.
The chosen answer in this question suggests to use code like the following:
ListViewItem item = myListView.ItemContainerGenerator.ContainerFromIndex(index) as ListViewItem;
However, that solution does not compile for me. I get the following error:
CS0039: Cannot convert type 'System.Windows.DependencyObject' to 'System.Windows.Forms.ListViewItem' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion.
I have already worked around an issue described in this question that relates to the wrong list item being used as the start point for the multi selection when the user shift-clicks, after programmatically setting the selected item. This is worked around by changing the SelectionMode before and after setting the selected item:
private MyItemType _selectedItem;
public MyItemType SelectedItem
{
get
{
return _selectedItem;
}
set // Use SetSelectedItemInternal() internally!
{
SetProperty(ref _selectedItem, value);
}
}
/// <summary>
/// Use this when programatically setting the SelectedItem. This method incorporates a workaround for a bug (?) in WPF
/// that causes confusing behaviour when shift-selecting items in the list after the SelectedItem is programatically changed.
/// See https://stackoverflow.com/questions/11950021/wpf-listview-shift-selecting-multiple-items-wrong-start-item
/// </summary>
private void SetSelectedItemInternal(MyItemType newSelectedItem, bool scrollToNewItem = true)
{
SelectionMode = SelectionMode.Single;
SelectedItem = newSelectedItem;
SelectionMode = SelectionMode.Extended;
if (scrollToNewItem)
{
ScrollToListItem(MyItemsSource.IndexOf(newSelectedItem));
}
}