I\'m trying to achieve the equivalent of a WinForms ListView
with its View
property set to View.List
. Visually, the following works fine.
It turns out that when it wraps around in my handling of the KeyDown
event, selection changes to the correct item, but focus is on the old item.
Here is the updated KeyDown
eventhandler. Because of Binding, the Items
collection returns my actual items rather than ListBoxItem
s, so I have to do a call near the end to get the actual ListBoxItem
I need to call Focus()
on. Wrapping from last item to first and vice-versa can be achieved by swapping the calls of MoveCurrentToLast()
and MoveCurrentToFirst()
.
private void thelist_KeyDown( object sender, KeyEventArgs e ) {
if ( object.ReferenceEquals( sender, thelist ) ) {
if ( thelist.Items.Count > 0 ) {
switch ( e.Key ) {
case Key.Down:
if ( !thelist.Items.MoveCurrentToNext() ) {
thelist.Items.MoveCurrentToLast();
}
break;
case Key.Up:
if ( !thelist.Items.MoveCurrentToPrevious() ) {
thelist.Items.MoveCurrentToFirst();
}
break;
default:
return;
}
e.Handled = true;
ListBoxItem lbi = (ListBoxItem) thelist.ItemContainerGenerator.ContainerFromItem( thelist.SelectedItem );
lbi.Focus();
}
}
}
You should be able to do it without the event listener using KeyboardNavigation.DirectionalNavigation, e.g.
<ListBox Name="thelist"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
KeyboardNavigation.DirectionalNavigation="Cycle">