2010-12-08 55 views
1

J'ai un WPF UserControl dans un WinForm:touche de capture dans un WPF

alt text

La partie verte est le WPF UserControl ..

Le code UserControl ci-dessous:

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnPreviewKeyUp(KeyEventArgs e) 
    { 
     base.OnPreviewKeyUp(e); 
     MessageBox.Show(e.Key.ToString()); 
    } 
} 

XAML:

<UserControl> 
    <Grid Background="DarkGreen"> 
     <Label Content="Label" Margin="64,105,0,0" Name="label1" /> 
    </Grid> 
</UserControl> 

Chaque fois que j'ouvre le tabPage2, je dois "écouter" les commandes du clavier.

Le code réel ne fonctionne pas (aucun message lorsque vous appuyez sur le clavier alors que l'onglet2 est ouvert).

Pourquoi?

EDIT 1

Mise à jour du code WinForms:

private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (this.tabControl1.SelectedIndex == 1) 
     { 
      ElementHost elHost = (this.tabControl1.SelectedTab.Controls[0] as ElementHost); 
      bool success = false; 
      if (elHost != null) 
      { 
       success = elHost.Focus(); 
       Console.WriteLine("Success : {0}", success); 
      }     
     } 
    } 

Résultat:

Function: WindowsFormsApplication2.Form1.tabPage2_Enter 
Function: WindowsFormsApplication2.Form1.tabControl1_SelectedIndexChanged 
Success : True 

Cependant, le résultat est le même: tout keyUp est capturé par le WPF UserControl.

Répondre

1

Les événements sont traités uniquement lorsque ElementHost a le focus. Voir here pour plus de détails.

private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    (this.tabControl1.SelectedTab.Controls[0] as ElementHost).Focus(); 
} 
0

Cela se produit car la messagerie est différente entre WinForms et WPF.

Voici une solution que j'ai trouvée pour cela.

Dans votre contrôle WinForms écouter les événements clés du contrôle WPF

_wpfHost.Child = MyWpfControl; 
MyWpfControl.Name = "MyWpfControl"; 

this.MyWpfControl.PreviewKeyDown += WpfControlOnPreviewKeyDown; 

Dans le WpfControlOnPreviewKeyDown faire votre logique. J'ai dû lancer l'événement vers un autre contrôle WinForms qui nécessitait les événements clavier.

private void WpfControlOnPreviewKeyDown(object sender, KeyEventArgs args) 
{ 
    if (args.Key != System.Windows.Input.Key.Enter) return; 

    // bubble up the event 
    var message = new System.Windows.Forms.Message { WParam = (IntPtr)Keys.Enter }; 
    this.ProcessKeyPreview(ref message); 
} 

Je n'avais besoin que de la touche d'entrée.