Отправить события клавиатуры из одной формы в другую форму - PullRequest
4 голосов
/ 01 июня 2010

мой вопрос довольно прост:

Наше приложение C # имеет одну MainForm с меню и несколько сочетаний клавиш, связанных с пунктами меню.

Теперь нам нужно запускать пункты меню также из некоторых дочерних форм. Но поскольку MainForm неактивна, когда активна одна из дочерних форм, ярлыки не работают.

Существует ли простой способ распространения всех событий клавиатуры от дочерней формы до формы «Владелец»? Или просто в другую форму вообще?

Ах, и мы не можем использовать некоторые низкоуровневые окна, потому что нам нужно запустить приложение и в Mono / Linux.

EDIT: Точная проблема у меня состоит в том, чтобы вызвать пункты меню с тем же ярлыком из другой формы. Конечно, без обновления кода в формах, если в меню добавлены изменения новых пунктов.

Ответы [ 7 ]

1 голос
/ 02 июня 2010

Вы пробовали что-то подобное?

ParentForm : Form
{
    public NotifyKeyPress(KeyPressEventArgs e)
    {
         OnKeyPress(e);
    }
}

ChildForm : Form
{
    ParentForm _parent;
    public ChildForm(ParentForm parent)
    {
       _parent = parent;
       KeyPress += KeyPressHandler;
    }

    public KeyPressHandler(object sender, KeyPressEventArgs e)
    {
       if (_parent != null)
       {
           _parent.NotifyKeyPress(e);
       } 
    }
}
1 голос
/ 16 февраля 2016

Вот что исправило это для меня:

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);
    }
}
0 голосов
/ 12 июня 2010

Вместо привязки сочетаний клавиш к элементам меню в главной форме вы можете создать собственный метод обработки клавиш, который реагирует на сочетания клавиш. Поместите этот метод в основную форму. Затем вызовите этот метод из всех дочерних форм ключевого события. Код @Adam Driscoll очень совместим с этим подходом.

0 голосов
/ 05 июня 2010

Существует гораздо более простой способ сделать это. Пункты меню должны вызывать соответствующие вызовы методов. Затем вы можете вызывать эти методы в любом месте приложения.

0 голосов
/ 04 июня 2010

Полагаю, под неактивным вы имеете в виду, что у него нет фокуса?

Самый чистый способ сделать это - показать каждой форме события, связанные с манипулированием их меню. Когда вы создаете формы, подписывайте их друг на друга (или от дочернего элемента до MainForm или любого другого способа, которым должен идти поток). При нажатии на меню выполните дополнительное событие, и другая форма получит это.

Это помогает? Я считаю, что это лучше, чем пытаться форсировать сообщение вручную, так как это будет самодокументированный код, который формы должны реагировать друг на друга.

Более подход "от проблемы", вам нужны две формы или вы можете реорганизовать дизайн пользовательского интерфейса?

0 голосов
/ 01 июня 2010

Свойство ToolStrip.AllowMerge "получает или устанавливает [...], является ли кратным MenuStrip , ToolStripDropDownMenu , ToolStripMenuItem и другие типы могут быть объединены. " (MSDN).

Это означает, что вы можете:

«Используйте свойство AllowMerge, чтобы разрешить дочерним элементам интерфейса с несколькими документами комбинировать свои соответствующие меню в родительском MDI». (Свойство AllowMerge, Remark, MSDN)

Смотри также:

  1. MergeAction
  2. MergeIndex

Это, я надеюсь, поможет вам получить то, что вы хотите. Теперь я не знаю, подходит ли это для Windows Forms или будет работать и в Linux после сборки.

0 голосов
/ 01 июня 2010

Я думаю, вы хотите установить KeyPreview в родительской форме на true

Если для этого свойства установлено значение true, форма будет получать все события KeyPress, KeyDown и KeyUp. После того, как обработчики событий формы завершили обработку нажатия клавиши, нажатие клавиши назначается элементу управления с фокусом. Например, если для свойства KeyPreview установлено значение true, а текущий выбранный элемент управления является TextBox, после того, как нажатие клавиши обработано обработчиками событий формы, элемент управления TextBox получит нажатую клавишу. Чтобы обрабатывать события клавиатуры только на уровне формы и не разрешать элементам управления получать события клавиатуры, установите для свойства KeyPressEventArgs.Handled в обработчике событий KeyPress формы значение true.

EDIT:

ответ в этот вопрос может быть полезным:

...