wpf - ListBox+WrapPanel tecla flecha de navegación
(2)
Debería poder hacerlo sin el detector de eventos usando KeyboardNavigation.DirectionalNavigation, por ejemplo
<ListBox Name="thelist"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
KeyboardNavigation.DirectionalNavigation="Cycle">
Estoy tratando de lograr el equivalente de un ListView
WinForms con su propiedad View
establecida en View.List
. Visualmente, lo siguiente funciona bien. Los nombres de archivo en mi Listbox
van de arriba a abajo, y luego se envuelven en una nueva columna.
Aquí está el XAML básico con el que estoy trabajando:
<ListBox Name="thelist"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"
Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Sin embargo, la navegación con la tecla de flecha predeterminada no se ajusta. Si se selecciona el último elemento en una columna, presionar la flecha hacia abajo no va al primer elemento de la siguiente columna.
Intenté manejar el evento KeyDown
así:
private void thelist_KeyDown( object sender, KeyEventArgs e ) {
if ( object.ReferenceEquals( sender, thelist ) ) {
if ( e.Key == Key.Down ) {
e.Handled = true;
thelist.Items.MoveCurrentToNext();
}
if ( e.Key == Key.Up ) {
e.Handled = true;
thelist.Items.MoveCurrentToPrevious();
}
}
}
Esto produce el comportamiento de último en la columna al primero en la siguiente columna que yo quería, pero también produce una rareza en el manejo de las flechas izquierda y derecha. Cada vez que se ajusta de una columna a la siguiente / anterior con las flechas arriba / abajo, un solo uso posterior de la tecla de flecha izquierda o derecha mueve la selección a la izquierda o a la derecha del elemento que se seleccionó justo antes de que se produzca el ajuste.
Supongamos que la lista está llena de cadenas "0001" a "0100" con 10 cadenas por columna. Si utilizo la tecla de flecha hacia abajo para ir de "0010" a "0011", luego presiono la tecla de la flecha hacia la derecha, la selección se mueve a "0020", justo a la derecha de "0010". Si se selecciona "0011" y utilizo la tecla de flecha hacia arriba para mover la selección a "0010", al presionar las teclas de flecha hacia la derecha se mueve la selección a "0021" (a la derecha de "0011", y una presión hacia la izquierda la tecla de flecha mueve la selección a "0001".
Se agradecería cualquier ayuda para lograr el diseño deseado de alineamiento de columna y la navegación con la tecla de flecha.
(Las ediciones se movieron a mi propia respuesta, ya que técnicamente es una respuesta).
Resulta que cuando se maneja el manejo del evento KeyDown
, la selección cambia al elemento correcto, pero el foco está en el elemento anterior.
Aquí está el KeyDown
eventos KeyDown
actualizado. Debido a Binding, la colección Items
devuelve mis elementos reales en lugar de ListBoxItem
s, así que tengo que hacer una llamada cerca del final para obtener el ListBoxItem
actual que necesito llamar Focus()
. El ajuste de la última posición a la primera y viceversa se puede lograr intercambiando las llamadas de MoveCurrentToLast()
y 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();
}
}
}