6
votes

Envoyer des événements clavier d'une forme à une autre forme

Ma question est assez simple:

Notre application C # possède une signalisation principale avec un menu et plusieurs raccourcis clavier associés aux entrées de menu.

Maintenant, nous devons également déclencher les entrées de menu de certaines formes d'enfants. Mais étant donné que le fond est inactif lorsque l'une des formes enfants est active, les raccourcis ne fonctionnent pas.

Y a-t-il un moyen simple de propager tous les événements de clavier de la forme enfant à la forme "propriétaire"? Ou juste à une autre forme en général?

ah, et nous ne pouvons pas utiliser de substances Windows de faible niveau, car nous devons également exécuter l'application sur Mono / Linux.

EDIT: Le problème exact que j'ai est de déclencher les éléments de menu avec le même raccourci d'une autre forme. Bien sûr, sans mettre à jour le code dans les formulaires si les modifications de menu des nouveaux éléments sont ajoutées.


3 commentaires

Je souhaite désespérément la réponse à cela aussi pour mon programme de montage.


ImessageFilter est disponible en mono, vous pouvez la mettre en œuvre pour votre formulaire principal.


hm ... pas sûr que si nous voulons faire face à cet objet de message .. Ou existe-t-il un moyen simple de transformer un tel message en événement?


7 Réponses :


0
votes

Je pense que vous voulez définir KeyPreview sur la forme parent à true

Lorsque cette propriété est définie sur True, le formulaire recevra toutes les événements KeyPress, Keydown et Keyup. Une fois les manipulateurs d'événements du formulaire ont terminé le traitement de la frappe, la touche de frappe est ensuite affectée au contrôle avec la mise au point. Par exemple, si la propriété KeyPreview est définie sur true et que le contrôle actuellement sélectionné est une zone de texte, une fois que la touche de frappe est traitée par les gestionnaires d'événements du formulaire, le contrôle de la zone Textbox recevra la touche appuyée. Pour gérer les événements du clavier uniquement au niveau du formulaire et ne permettez pas aux contrôles de recevoir des événements de clavier, définissez la propriété KeighpresserEventargs.Handled dans le gestionnaire d'événements KeyPress de votre formulaire à True.

EDIT:

La réponse dans Cette question pourrait être utile:


4 commentaires

Cela ne provoque que le traitement des événements clés reçus ses contrôles.


Bonne idée, mais cela n'a pas aidé, car le MainForm n'est que le «propriétaire» des formes de l'enfant, mais pas le «parent» dans le sens de .NET (ma nommée dans le poste n'était pas claire à ce sujet, désolé) . Lorsque j'essaie de définir la propriété "parent", je reçois une exception, car un formulaire est un contrôle de toplevel. Toutes les autres idées?


édité ma réponse comme ce que j'ai fourni pour la première fois ne fait pas ce que vous voulez.


La solution que vous avez suggérée dans votre édition semble similaire à Adam Driscolls Solution, je vais essayer cela.



0
votes

Le Toolstrip.allmergerge propriété "obtient ou définit [...] si plusieurs Menustrip , ToolstripDropDownMenu , Toolstripmenuitem et d'autres types peuvent être combinés." (MSDN).

Cela signifie que vous pouvez:

"Utilisez la propriété autorisée pour activer les enfants d'interface multiple (MDI) de combiner leurs menus respectifs dans le parent MDI." (Propriété, remarque, MSDN)

Voir aussi:

  1. Mergeaction < / a>
  2. Mergeindex

    Ceci, j'espère, vous aidera à obtenir ce que vous voulez. Maintenant, je ne sais pas si cela convient aux formulaires Windows ou si cela fonctionnera également sur Linux une fois construit.


2 commentaires

Voir l'autre post, nous n'avons pas d'autres menus à rejoindre ou à fusionner. Ou comment vouliez-vous dire que cela pourrait résoudre le problème?


Vous devez avoir une menuisse sur le conteneur MDI et le formulaire enfant. Ensuite, vous leur permettez de fusionner, même de remplacer certains des menus équivalents les uns des autres.



1
votes

Avez-vous essayé quelque chose comme ça? XXX


3 commentaires

Oui, je suppose que cela pourrait fonctionner, je vais essayer et rapporter .. Thnx!


bonjour à nouveau, il ne fonctionne pas comme ça .. Je peux envoyer les événements du clavier sur le terrain principal et appeler l'événement OnKeyxxx, mais cela ne déclenche pas les événements dans les ménulseurs. C'est vraiment un problème étrange .. Je pensais que ce serait Soyez plus facile ...


Peut-être essayez peut-être d'utiliser ShakkeyEvent.



0
votes

Je présume en inactif, vous voulez dire qu'il n'a pas de concentration?

Le moyen le plus propre de le faire est de disposer de chaque formulaire exposé aux événements liés à leurs menus manipulés. Lorsque vous créez les formulaires, installez-les les uns aux autres (ou de l'enfant à la forme principale ou de la manière dont le flux doit aller). Lorsque le menu est cliqué sur le menu, exécutez votre événement supplémentaire et l'autre formulaire recevra cela.

Est-ce que cela aide? Je crois que cela vaut mieux que d'essayer de forcer un message manuellement car il sera auto-documentant du code que les formulaires doivent se réagir à l'autre.

Un approche plus "loin du problème", avez-vous besoin de deux formes ou pouvez-vous refactoriser la conception de l'interface utilisateur?


2 commentaires

Bonjour, merci pour votre réponse! Nous n'avons qu'un seul menu, c'est-à-dire sous la forme principale, mais chaque formulaire doit être capable de déclencher les éléments de menu avec des raccourcis clavier. Nous n'avons pas besoin d'un autre menu sous une autre forme et nous n'avons pas besoin de notifier d'autres formulaires si un élément de menu a été cliqué. Donc, ça ne va pas vraiment aider ..


Ah .. et oui .. Je pourrais refacturer la conception de l'interface utilisateur. Quelle serait votre idée alors?



0
votes

Il y a beaucoup plus simple de faire cela. Les éléments de menu doivent déclencher des appels de méthode appropriés. Ensuite, vous pouvez appeler ces méthodes n'importe où dans l'application.


1 commentaires

Oui, je peux le faire, mais je veux les déclencher avec les mêmes raccourcis clavier d'autres formes. Et je veux définir le raccourci une seule fois bien sûr ...



0
votes

au lieu de raccourcir les raccourcis des touches des éléments de menu sur le formulaire principal, vous pouvez créer une méthode de traitement de clé personnalisée qui réagit aux raccourcis de clé. Mettre cette méthode dans la forme principale. Ensuite, appelez cette méthode de tous les formulaires enfants sur un événement clé. Le code de Driscoll @adam est très compatible avec cette approche.


0 commentaires

4
votes

C'est ce qui lui est réparé pour moi:

public class MainForm : Form
{
    public bool ProcessCmdKeyFromChildForm(ref Message msg, Keys keyData)
    {
        Message messageCopy = msg;
        messageCopy.HWnd = this.Handle; // We need to assign our own Handle, otherwise the message is rejected!

        return ProcessCmdKey(ref messageCopy, keyData);
    }
}

public class MyChildForm : Form
{
    private MainForm mMainForm;

    public MyChildForm(MainForm mainForm)
    {
        mMainForm = mainForm;
    }

    // This is meant to forward accelerator keys (eg. Ctrl-Z) to the MainForm
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (mMainForm.ProcessCmdKeyFromChildForm(ref msg, keyData))
        {
            return true;
        }

        return base.ProcessCmdKey(ref msg, keyData);
    }
}


3 commentaires

C'est une excellente solution qui a sauvé ma journée, merci. Cependant, si je peux, s'il vous plaît, veillez à ce que message Messagecopy = msg; effectue uniquement une copie peu profonde du message. La ligne suivante entraîne ainsi une modification du message d'origine. Je recommande de créer un nouveau message et de copier tous les champs (sauf hwnd évidemment)


@Couitchy Cheers! Hmm, je suis sûr que c'est une copie profonde, car le message est un type de valeur (struct): docs.microsoft.com/en-us/dotnet/api/... . Heureux d'être prouvé faux (je modifierai le message si c'est le cas).


Salut @kostasvs! Je viens de vérifier et il semble que vous ayez parfaitement raison: c'est en effet une copie profonde. En fait, chaque fois que je vois le mot-clé ref , cela me fait penser à un type de référence, mais j'aurais dû penser que message était un struct .