wpf xaml listview textbox datatemplate

wpf - ¿Cómo TAB a través de ListView con TextBoxes como TreeViewItems?



wpf listview grouping (3)

Eche un vistazo a KeyboardNavigation.TabNavigation Attached Property

Así que básicamente tengo este ListView y me gustaría presionar Tab e iterar a través de mi TreeViewItems (preferiblemente solo mis TextBoxes)

<ListView> <ListView.View> <GridView> <GridViewColumn Header="number" /> <GridViewColumn Header="Selector"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding SelectorName}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>

El escenario que estoy viendo es después de presionar la pestaña por primera vez, se selecciona todo el primer TreeViewItem y al presionar Tab nuevamente, se selecciona el primer TextBox. Finalmente, la tercera TAB sale del TreeView al siguiente Control aunque hay más TextBoxes que Me gustaría atrapar antes de "tabular" para el próximo control. Thankx

Editar: la pregunta fue respondida aquí: cómo TAB a través de cuadros de texto en un ListView


Establezca IsTabStop = "False" en la GridViewColumn y en la plantilla de la celda. Ahora debería seleccionar solo el TextBox dentro de la Plantilla de datos en el cambio de pestaña.

Prueba esto:

<ListView DataContext="List" IsTabStop="False" > <ListView.View> <GridView> <GridViewColumn Header="Name" /> <GridViewColumn Header="Selector"> <GridViewColumn.CellTemplate> <DataTemplate > <TextBox Text="{Binding Name}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>


Tal vez me falta algo pero no puedo encontrar ningún método simple para hacer esto, aquí hay un resumen de lo que podrías hacer:

<ListView.InputBindings> <KeyBinding Key="Tab" Command="{Binding GoToNextItem}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ListView}}" /> <KeyBinding Modifiers="Shift" Key="Tab" Command="{Binding GoToPreviousItem}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ListView}}" /> </ListView.InputBindings> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <EventSetter Event="Selected" Handler="ItemSelected" /> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <GridViewColumn Header="number" /> <GridViewColumn Header="Selector"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBox Name="_tb" Text="{Binding SelectorName}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View>

Cosas que hice aquí:

  • Anula el comportamiento de la pestaña para disparar comandos para seleccionar otro elemento
  • Agregar controlador de eventos al evento seleccionado para enfocar el TextBox
  • Nombre TextBox para que pueda ser encontrado y enfocado

Código:

private readonly ICommand _GoToNextItem = new Command((p) => { var lv = p as ListView; if (lv.SelectedIndex == -1 || lv.SelectedIndex == lv.Items.Count - 1) { lv.SelectedIndex = 0; } else { lv.SelectedIndex++; } }); public ICommand GoToNextItem { get { return _GoToNextItem; } } private readonly ICommand _GoToPreviousItem = new Command((p) => { var lv = p as ListView; if (lv.SelectedIndex <= 0) { lv.SelectedIndex = lv.Items.Count - 1; } else { lv.SelectedIndex--; } }); public ICommand GoToPreviousItem { get { return _GoToPreviousItem; } }

private void ItemSelected(object sender, RoutedEventArgs e) { var item = sender as ListBoxItem; (FindNamedChild(item, "_tb") as TextBox).Focus(); } public static object FindNamedChild(DependencyObject container, string name) { if (container is FrameworkElement) { if ((container as FrameworkElement).Name == name) return container; } var ccount = VisualTreeHelper.GetChildrenCount(container); for (int i = 0; i < ccount; i++) { var child = VisualTreeHelper.GetChild(container, i); var target = FindNamedChild(child, name); if (target != null) { return target; } } return null; }

Esto es muy incompleto, use cualquier parte de este bajo su propio riesgo. ( El enfoque también podría haber sido hecho de manera diferente sin traer la selección a esto, creo )

( La clase Command es solo una implementación genérica de ICommand que toma una lambda que se ejecuta en el método Execute la interfaz )