2011-12-17 36 views
10

Tenemos una aplicación basada en WPF .NET 4.0 C#. Construimos nuestra interfaz de usuario a partir de definiciones XML (no XAML) pero debajo usamos un WPF para presentar la UI. Es decir, en tiempo de ejecución, creamos la interfaz de usuario de WPF según nuestra definición XML.Navegación con la tecla de tabulación WPF

Tenemos un problema con la navegación de pestañas. Configuramos TabStop, TabIndex, para controles de texto y cuadros combinados.
Pero la navegación con pestañas no funciona. ¿Cómo hacer que la navegación con pestañas funcione para este diseño?

enter image description here

+4

Cómo ¿está configurando las propiedades de TabIndex para sus controles en el código subyacente para esta interfaz? Debe ser más claro sobre lo que no funciona. Publica un código – Bernard

+4

¿Qué quiere decir con "no funciona"? ¿Es "presionas Tab pero el foco no se mueve"? O se mueve, pero se mueve mal? ¿De qué manera está mal? –

+0

¿Ha mirado la clase [KeyboardNavigation] (http://msdn.microsoft.com/en-us/library/aa969768.aspx#Keyboard_Navigation)? – rfmodulator

Respuesta

8

usted debe tratar de establecer un KeyboardNavigation.TabNavigation propiedad adjunta a ambos de su control Tree, o el control StackPanel derivada, en caso de que desea que sus botones inferiores a participar también en un ciclo de pestaña:

<controls:CustomStackPanel KeyboardNavigation.TabNavigation="Cycle"> 
<Tree> 
... 
</Tree> 
</controls:CustomStackPanel> 

Incluso puede combinar un enfoque de código subyacente que, supongo, está tratando de usar para controlar el comportamiento de las pestañas dentro del control Tree, con el KeyboardNavigation.TabNavigation para encargarse de las pestañas fuera del control de árbol.

29

WPF trata todo el árbol de la interfaz de usuario como un único ámbito de pestaña. No se divide en áreas más pequeñas, como cabría esperar. Esto incluye controles dentro de UserControls.

Por ejemplo, si usted tenía

<StackPanel> 
    <TextBox Name="TextBox1" /> 
    <MyUserControl /> 
    <TextBox Name="TextBox3" /> 
</StackPanel> 

Y MyUserControl parecía

<MyUserControl> 
    <TextBox Name="TextBox2" /> 
</MyUserControl> 

El ciclo pestaña predeterminada sería TextBox1, TextBox2 TextBox3. Esto se debe a que no se definen las propiedades de TabIndex, por lo que todos los controles se ejecutan en el orden de tabulación predeterminado, que es el orden en que se agregan a la interfaz de usuario.

Si se establece el ÍndiceDeTabulación en sus controles tales como abajo,

<StackPanel> 
    <TextBox Name="TextBox1" TabIndex="1" /> 
    <MyUserControl TabIndex="2" /> 
    <TextBox Name="TextBox3" TabIndex="3" /> 
</StackPanel> 

Su tabulación cambiaría a TextBox1, TextBox3, TextBox2. Esto se debe a que TextBox2 no tiene un TabIndex especificado, por lo que se asume el valor predeterminado y se asigna a una pestaña después de que todos los otros controles con un TabIndex especificado pasan por un ciclo.

La forma en que normalmente soluciono esto es unir el TabIndex de los controles dentro del UserControl al UserControl.TabIndex.

Por ejemplo añadiendo el siguiente enlace al control de usuario haría que el ciclo ficha correcta de nuevo

<MyUserControl> 
    <TextBox Name="TextBox2" TabIndex="{Binding Path=TabIndex, RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}}" /> 
</MyUserControl> 

Por lo general prefieren para establecer esta unión en el Loaded caso del control de usuario en lugar de tener que recordar para establecer esta unión en todos los controles dentro del UserControl. Estoy seguro de que también hay formas más eficientes de hacerlo, sin embargo, el problema no ha surgido con la frecuencia suficiente para que me siente y me tome el tiempo de investigar cómo usar los ámbitos de las pestañas correctamente para evitar esta solución alternativa.

5

No es una respuesta per-se pero las pestañas de WPF son extremadamente complicadas. Requiere establecer las propiedades TabNavigation, IsTabStop en Xaml y manipular el alcance del foco. Pasé varios días tratando de hacer pestañas con Xaml solo. Sugeriría comenzar con su XML -> ¡El modelo de WPF realmente debería ser Xaml -> WPF!Sin embargo, me imagino que eso no es posible.

¿Qué tal esto para una solución alternativa. ¿Es posible manejar la tabulación en el código generado? Si tus propios controles de usuario de WPF son generados por tu propio software desde tu propio XML, te sugiero que coloques un elemento TabOrder en tu XML y luego lo uses para conectar un evento TabOut.

mira el siguiente ejemplo de código para forzar una operación de movimiento en el código (similar a Tabbing)

// Creating a FocusNavigationDirection object to perform the tab operation 
// values include Next, Previous, First, Last etc... 
FocusNavigationDirection focusDirection = FocusNavigationDirection.Next; 

// MoveFocus takes a TraveralReqest as its argument. 
TraversalRequest request = new TraversalRequest(focusDirection); 

// Gets the element with keyboard focus. 
UIElement elementWithFocus = Keyboard.FocusedElement as UIElement; 

// Change keyboard focus. 
if (elementWithFocus != null) 
{ 
    elementWithFocus.MoveFocus(request); 
} 

En segundo alambre en la KeyUp (o PreviewKeyUp) caso de los controles "tabbable" y si la clave fue una pestaña llamar al código anterior para hacer que el foco salte al siguiente elemento.

La muestra del código anterior básicamente forzará en el código lo que WPF debería hacer de la caja. Como han sugerido otros carteles Me gustaría ir a través de su código de WPF generada a ver lo que los valores de KeyboardNavigation.IsTabStop y KeyboardNavigation.TabNavigation

Saludos,

+0

no estoy seguro de manejar la pestaña explícitamente en general, eso parece un poco hacky. Sin embargo, +1 para las cosas de MoveFocus: descubrí que lo necesitaba para manejar una pestaña shift + para un control personalizado donde algunas cosas cambiaban su visibilidad. –

0

Trate KeyboardNavigation.TabNavigation = "Una vez"

Cuestiones relacionadas