2012-01-31 8 views
5

Tengo muchas aplicaciones viejas de Windows Forms que eventualmente serán portadas a WPF (es una aplicación grande por lo que no se puede hacer en un sprint), y comencé el proceso creando un menú principal en WPF. Las aplicaciones de Windows Forms son ventanas separadas que se abren desde este menú.Las teclas y pestañas Alt no funcionan en Windows Forms abierto desde una aplicación WPF

El aplicaciones de Windows Forms se están abriendo y trabajando sin ningún problema, excepto los problemas que estoy teniendo con el acceso directo y Tab llaves. La tecla de tabulación no mueve el foco al siguiente control y la tecla Alt para activar el botón de búsqueda & ya no funciona.

¿Qué estoy haciendo mal?

Respuesta

3

Finalmente logré solucionar el problema alojando el formulario winform dentro de un control WindowsFormsHost dentro de un formulario WPF.

public partial class MyWindow : Window 
{ 
    public MyWindow() 
    { 
     InitializeComponent(); 

     Form winform = new Form(); 
     // to embed a winform using windowsFormsHost, you need to explicitly 
     // tell the form it is not the top level control or you will get 
     // a runtime error. 
     winform.TopLevel = false; 

     // hide border because it will already have the WPF window border 
     winform.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
     this.windowsFormsHost.Child = winform; 
    } 

} 

Tenga en cuenta que es posible que tenga que conectar el evento de cierre WinForm si tiene un botón para cerrar el formulario.

1

Compruebe si se han asignado IsTabStop="True" y TabIndex. Para el atajo Alt + Key, intente utilizar el carácter de guión bajo (_) en lugar del símbolo comercial (&).

+0

Sí, isTabStop = "true" para todos los controles relevantes. La funcionalidad funciona perfectamente cuando abro el formulario desde un menú de winforms, solo se rompe cuando abro exactamente el mismo formulario desde un menú de WPF. No estoy seguro de lo que quiere decir con el uso del subrayado. Además, una letra en el texto del botón se mostrará como un guión bajo cuando se represente el control :) – Franchesca

+0

@Franchesca Supuse que estaba convirtiendo todos sus winforms a WPF. Buena suerte con tu conversión! – SliverNinja

+0

ah, ya veo. ¡¡¡Gracias por tu ayuda!!! : D – Franchesca

3

Esto es por diseño. Las teclas de atajo se manejan en el nivel de bucle de mensaje, se detectó antes de el mensaje de Windows se envía a la ventana con el foco. Esa es la razón por la que esas teclas pueden funcionar independientemente del enfoque.

El problema es que no tiene el bucle de mensajes de Winforms bombeando los mensajes. Application.Run() es implementado por WPF en su programa, no en Winforms. Por lo tanto, no se ejecutará ninguno de los códigos en Winforms que procesa mensajes de teclado para implementar combinaciones de teclas de método abreviado.

No hay una buena solución para esto, es básicamente el problema de "no puede quedar un poco embarazada". Este código en Winforms está bloqueado en gran medida ya que permitiría CAS bypass. La única solución consiste en mostrar una clase derivada de Formulario que contiene controles Winforms con su método ShowDialog(). Ese método bombea un bucle de mensaje modal, el de Winforms, lo suficientemente bueno como para reactivar el código de manejo de teclas rápidas. Reestructurar su enfoque convirtiendo primero las ventanas principales, los diálogos duran.

+1

Gracias por la respuesta detallada. El [WindowsFormsHost] (http://msdn.microsoft.com/en-us/library/ms751797.aspx) parece ser lo único que facilita la transferencia de teclas de método abreviado. Sin embargo, está diseñado para controles, no para formularios de "nivel superior" (por lo que se requiere cierta piratería). – Franchesca

+0

¡El uso de 'ShowDialog()' resuelve el problema de las pestañas y fue muy útil para mí! Espero que otros programadores encuentren esta solución aquí (fue difícil para mí encontrarla) – zee

2

Una solución parcial que descubrí es llamar esto desde su constructor de WPF: System.Windows.Forms.Integration.WindowsFormsHost.EnableWindowsFormsInterop(); (Debe hacer referencia al archivo dll WindowsFormsIntegration.dll)

Digo parcial porque no todas las teclas funcionan como se esperaba. Por ejemplo, parece funcionar bien para formas simples.

ver esto:
http://msdn.microsoft.com/en-us/library/system.windows.forms.integration.windowsformshost.enablewindowsformsinterop(v=vs.100).aspx

+0

Eso es interesante, no sabía que podrías hacerlo de esa manera. ¡Gracias! – Franchesca

2

Otra solución que encontré de gestionar la selección en el Tab clave es reemplazar OnKeyDown así:

protected override void OnKeyDown(KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.Tab) 
    { 
     HandleFocus(this, ActiveControl); 
    } 
    else 
    { 
     base.OnKeyDown(e); 
    } 
} 

internal static void HandleFocus(Control parent, Control current) 
{ 
    Keyboard keyboard = new Keyboard(); 
    // Move to the first control that can receive focus, taking into account 
    // the possibility that the user pressed <Shift>+<Tab>, in which case we 
    // need to start at the end and work backwards. 
    System.Windows.Forms.Control ctl = parent.GetNextControl(current, !keyboard.ShiftKeyDown); 
    while (null != ctl) 
    { 
     if (ctl.Enabled && ctl.CanSelect) 
     { 
      ctl.Focus(); 
      break; 
     } 
     else 
     { 
      ctl = parent.GetNextControl(ctl, !keyboard.ShiftKeyDown); 
     } 
    } 
} 

La ventaja de esta solución es que doesn No requiere ni WindowsFormsHost ni una bomba de mensajes, lo que puede ser complicado de implementar.Pero no sé si es posible manejar teclas de acceso directo como esta porque no las necesitaba.

+0

Ese es un enfoque interesante, podría ser una buena alternativa para alguien :) – Franchesca

Cuestiones relacionadas