我的问题很简单:
我们的C#应用程序有一个带有菜单的MainForm和几个与菜单项相关联的键盘快捷键。
现在我们还需要从某些子窗体中触发菜单项。但是,由于当其中一个子窗体处于活动状态时,MainForm处于非活动状态,因此快捷方式不起作用。
是否有一种简单的方法可以将所有键盘事件从子表单传播到“所有者”表单?或者只是另一种形式?
啊,我们不能使用一些低级别的东西,因为我们也需要在Mono / Linux上运行应用程序。
编辑: 我遇到的确切问题是从另一个表单触发具有相同快捷方式的菜单项。当然,如果添加新项目的菜单更改,则不会更新表单中的代码。
答案 0 :(得分:1)
你尝试过这样的事吗?
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 :(得分:1)
这就是为我解决的问题:
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);
}
}
答案 2 :(得分:0)
我认为您希望将父表单上的KeyPreview设置为true
当此属性设置为true时,表单将接收所有KeyPress,KeyDown和KeyUp事件。在表单的事件处理程序完成键击处理之后,然后将键击分配给具有焦点的控件。例如,如果KeyPreview属性设置为true并且当前选定的控件是TextBox,则在通过窗体的事件处理程序处理击键后,TextBox控件将接收按下的键。要仅在表单级别处理键盘事件而不允许控件接收键盘事件,请将表单的KeyPress事件处理程序中的KeyPressEventArgs.Handled属性设置为true。
编辑:
this question中的答案可能会有所帮助:
答案 3 :(得分:0)
ToolStrip.AllowMerge
属性“获取或设置[...]是否可以合并多个MenuStrip,ToolStripDropDownMenu,ToolStripMenuItem和其他类型。” (MSDN)。
这意味着你可以:
“使用AllowMerge属性启用多文档界面(MDI)子级,以便在MDI父级中组合各自的菜单。” (AllowMerge属性,备注,MSDN)
另见:
我希望,这会帮助你得到你想要的东西。现在,我不知道这是否适用于Windows Forms,或者它是否也可以在Linux上运行。
答案 4 :(得分:0)
我认为不活跃你的意思是它没有焦点?
最简洁的方法是让每个表单公开与其操作菜单相关的事件。创建表单时,请相互订阅(或从子节点到MainForm或流程需要的任何方式)。单击菜单后,执行额外的事件,另一个表单将收到此信息。
这有帮助吗?我认为这比尝试手动强制消息更好,因为它将是表单需要相互作出反应的自我记录代码。
更“远离问题”的方法,您需要两种形式还是可以重构UI设计?
答案 5 :(得分:0)
有更简单的方法可以做到这一点。菜单项应触发适当的方法调用。 然后你可以在应用程序的任何地方调用这些方法。
答案 6 :(得分:0)
您可以创建一个对密钥快捷方式作出反应的自定义密钥处理方法,而不是将快捷键绑定到主窗体上的菜单项。将此方法放在主窗体中。然后从关键事件的所有子窗体调用此方法。 @Adam Driscoll的代码与这种方法非常兼容。