尝试使用ProcessCmdKey在MDI父/子窗体和其他窗体中实现全局键盘快捷键
我在 MDI 父表单类中重写 ProcessCmdKey() ,并在同一个类中有一些键盘快捷键调用方法。但我希望使这些热键以父/子形式和其他形式工作。现在的情况是,当焦点放在其他表单(常规表单,而不是 MDI)上时,ProcessCmdKey() 不再捕获键盘。我应该将 ProcessCmdKey() 放入哪个类以及任何使其工作的内容?谢谢!
namespace myNamespace
{
public class MDIParent : System.Windows.Forms.Form
{
public bool NextTab(){...}
public bool PreviousTab(){...}
protected override bool ProcessCmdKey(ref Message message, Keys keys)
{
switch (keys)
{
case Keys.Control | Keys.Tab:
NextTab();
return true;
case Keys.Control | Keys.Shift | Keys.Tab:
PreviousTab();
return true;
}
return base.ProcessCmdKey(ref message, keys);
}
}
public class mySecondForm : System.Windows.Forms.Form
{
...
}
}
I override ProcessCmdKey() in my MDI parent form class and have some keyboard shortcut calling method in same class. But I wish to make these hotkeys working in parent/child form and other form. The case now is when focus on the other form(regular form, not MDI), ProcessCmdKey() doesn't capture keyboard anymore. Which class should I put ProcessCmdKey() in and anything to make it work? Thanks!
namespace myNamespace
{
public class MDIParent : System.Windows.Forms.Form
{
public bool NextTab(){...}
public bool PreviousTab(){...}
protected override bool ProcessCmdKey(ref Message message, Keys keys)
{
switch (keys)
{
case Keys.Control | Keys.Tab:
NextTab();
return true;
case Keys.Control | Keys.Shift | Keys.Tab:
PreviousTab();
return true;
}
return base.ProcessCmdKey(ref message, keys);
}
}
public class mySecondForm : System.Windows.Forms.Form
{
...
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用实现的 ProcessCmdKey 处理程序定义一个“基本”表单,然后创建所有其他表单:MDI 父级、MDI 父级的子窗口以及您创建的任何“独立”表单(即不是 MDI 的子级) Form) 继承自“基本 Form”。只需确保在您希望成为 MDI 的窗体上设置 IsMdiContainer 属性,并且添加到 MDI 窗体的子窗口不是 TopLevel 并且将其父窗口设置为 MDI 窗体。
那么问题是,您想要在哪里处理由您启用的组合键触发的事件,因为...如果您定义由基本 Form 中的捕获组合键触发的方法...继承的每个 Form从基本表单将在它们自己的上下文中执行它们。
如果您想在应用程序范围内处理捕获的按键组合,请实现一个静态公共类,并将按键组合处理程序定义为静态方法。或者,由于您可能想知道从哪个表单发出的特殊组合键,只需将调用 Form 的指针传递给静态处理程序即可。
因此,基本 Form 中 ProcessCmdKey 覆盖中的控件 + Tab 的处理程序可能如下所示:
您的静态类可能如下所示:
正如您在上面的代码中看到的,您可以使用调用 Form 的 ActiveControl 属性了解给定类型的表单上的哪个控件获得了组合键。
当然,如果您不想像这样“全局”处理键组合,只需在其他表单中根据需要插入 ProcessCmdKey 覆盖,并且不要让它们从基本表单继承。
处理“应用程序范围内”的关键事件可能是也可能不是您的特定解决方案的最佳策略,但它是一个可行的策略。最好的,
You can define a "base" Form with your ProcessCmdKey handler implemented, and then make all your other Forms : the MDI Parent, the Child Windows of the MDI Parent, and any "Independent" Forms you create (i.e., not children of the MDI Form) inherit from the "base Form." Just make sure the IsMdiContainer property is set on the form you wish to be MDI, and the child windows you add to the MDI Form are not TopLevel and have their parent set to the MDI Form.
The question is, then, where do you want to handle the events triggered by the key combinations you've enabled because ... if you define methods to be triggered by the trapped key combinations in the base Form ... each Form that inherits from the base Form is going to execute them in their own context.
If you want to handle the trapped key-combinations on an application wide basis, then implement a static public class with the key-combination handlers defined as static methods there. Or, since you may want to know from which form the special key-combinations issued just pass a pointer to calling Form to the static handler.
So, your handler for the control + Tab in the ProcessCmdKey override in the base Form might look like this :
Your static class might look something like this :
As you can see in the code above, you can use the ActiveControl property of the calling Form to know which control on a given type of Form got the key-combination.
Of course, if you don't want to handle the key-combinations "globally," like this, just insert your ProcessCmdKey over-rides as needed in the other Forms, and don't have them inherit from the base Form.
Handling the key events "application wide" may, or may not be the best strategy for your particular solution, but it is a viable strategy. best,