2012-05-04 18 views
6

¿Cómo puedo en el código definir el foco lógico de un contenedor o un elemento secundario enfocado, SIN dándole el foco en el teclado?¿Cómo establecer el enfoque lógico sin dar prioridad al teclado?

Solo quiero controlar qué niño obtendrá el foco cuando el control se enfocará mediante la tecla Tab o haciendo clic en parte del contenedor que no golpea a un niño, pero no le da (o roba) el foco real si ya no lo tiene.

Y también quiero que sea posible seleccionar un niño específico mediante un gesto de teclado o hacer clic en él con el mouse.

Entiendo la diferencia en WPF entre Keyboard Focus y Logical Focus, y el hecho de que para un elemento, tener Keyboard Focus implica también tener un enfoque lógico, pero tener un enfoque lógico no implica que el elemento tenga el foco del teclado.

También entiendo que la propiedad adjunta FocusManager.FocusedElement define qué elemento tiene un enfoque lógico en el árbol visual que comienza en el elemento que define esta propiedad.

Me di cuenta de que esta propiedad no se usa solo cuando FocusManager.IsFocusScope está establecido en verdadero, sino también para contenedores como GroupBox.

He hecho muchos intentos, toneladas de búsquedas y la lectura en tema central de WPF, pero sin éxito hasta el momento, no entiendo lo que me falta:

  • Calling FocusManager.SetFocusedElement también dar el foco del teclado, y Puedo cambiar temporalmente la enfocable propiedad de mi elemento secundario en false justo antes, sólo funciona la primera vez, cuando ningún niño se había seleccionado antes, pero no después de que un niño tiene centran
  • eventos Manejo GotKeyboardFocus y PreviewGotKeyboardFocus en elemento o contenedor para reemplazar elemento enfocado inicial tampoco funciona, ya que no puedo decir si el enfoque se obtuvo con el mouse o el teclado, y si el foco se ajustó directamente a un elemento secundario o indirectamente a través del contenedor.
  • un ejemplo para ilustrar lo que estoy tratando de lograr: Tengo un simple grupo de RadioButtons, y yo quiero controlar dinámicamente en el código de la opción que obtener el foco cuando el usuario se “Tab” para mover el foco a este GroupBox (generalmente la opción que tiene isChecked=true).

    <GroupBox Header="Options" Name="myGroupBox" 
          KeyboardNavigation.TabNavigation="Once" 
          KeyboardNavigation. DirectionalNavigation="Cycle" > 
        <StackPanel> 
         <RadioButton GroupName="g1" Name="opt1" Content="Option _1"/> 
         <RadioButton GroupName="g1" Name="opt2" Content="Option _2"/> 
         <RadioButton GroupName="g1" Name="opt3" Content="Option _3"/> 
        </StackPanel> 
    </GroupBox> 
    

    Un comentario final, sé cómo implementar una lista dinámica de opciones utilizando un ListBox, unión selectedItem de la lista a una propiedad del contexto de datos, y luego a través de estilos y plantillas en ListBoxItem unen IsChecked propiedad del RadioButton en plantilla de elementos de IsSelcted propiedad de su padre ListBoxItem, y funciona, pero para mi caso concreto, necesito t o mantener mi RadioButtons directamente ligado a las propiedades de mi contexto de datos, no puedo vincularlos a la propiedad IsSelected de la lista al mismo tiempo.

    +0

    intente establecer FocusManager.IsFocusScope = verdadero para GroupBox –

    +0

    Gran pregunta, estoy buscando esta respuesta yo mismo ... – Doug

    Respuesta

    1

    Sé que esta es una pregunta antigua pero espero que esta respuesta ayude a otros con un problema similar.

    Si entiendo el problema correctamente, puede lograr el comportamiento deseado configurando FocusManager.IsFocusScope = "True" en el GroupBox, y conecte un controlador de eventos para el evento RadioButton.Checked que establece el Enfoque Lógico para el remitente del evento:

    Xaml:

     <GroupBox Header="Options" Name="myGroupBox" 
           FocusManager.IsFocusScope="True" 
           RadioButton.Checked="MyGroupBox_OnChecked" 
           KeyboardNavigation.TabNavigation="Once" 
           KeyboardNavigation.DirectionalNavigation="Cycle"> 
         <StackPanel> 
          <RadioButton GroupName="g1" Name="opt1" Content="Option _1"/> 
          <RadioButton GroupName="g1" Name="opt2" Content="Option _2"/> 
          <RadioButton GroupName="g1" Name="opt3" Content="Option _3"/> 
         </StackPanel> 
        </GroupBox> 
    

    Código atrás:

    private void MyGroupBox_OnChecked(object sender, RoutedEventArgs e) 
        { 
         var radioB = sender as RadioButton; 
         if (radioB != null) 
          FocusManager.SetFocusedElement(myGroupBox, radioB); 
        } 
    
    +0

    Como dijo el OP, FocusManager.SetFocusedElement * a veces * también le da enfoque al teclado, no solo al enfoque lógico. http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.setfocusedelement(v=vs.110).aspx "e intentará dar al foco del teclado del elemento". –

    Cuestiones relacionadas