【问题标题】:Same Main Menu across all forms - winforms .net所有表单的主菜单相同 - winforms .net
【发布时间】:2017-09-25 12:24:49
【问题描述】:

我想在我的应用程序中的所有打开的表单中使用一个 MainMenuStrip。我不想在所有表单上显示相同的 MainMenu,而是 MainMenu 应该只出现在我的 MainForm 上,并且应该可以从我的所有其他表单访问。

所需的行为与 Visual Studio 2013 中的相同(可能其他版本也是如此)。如果一个文档是浮动的并且您点击了 ALT 按钮或任何组合,例如ALT+F,MainWindow 出现在前面并且 MainMenu 是可见的,尽管 MainWindow 似乎没有被激活。当您再次按下 ALT 按钮时,焦点将返回到浮动窗口。

当按下菜单键时,我尝试将消息从同级表单转发到 MainForm,但 MainForm 需要成为前台窗口才能处理消息 - 正如我在 .net 源代码中看到的那样。 https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ToolStripManager.cs,1680

我不想使用 MDI - 我只想拥有与 MDI 中相同的菜单行为。

如果有人对如何实现这一点有任何建议,我将非常感激。

【问题讨论】:

  • 当点击菜单热键时记住表格,激活主表格,显示菜单。当菜单关闭时 - 激活以前的表格。还是我错过了什么?
  • 这个问题和命令行界面有什么关系?那个标签似乎无关。
  • 标签应该是 c++/cli 中的 cli
  • 你有一个很好的答案,但我仍然很好奇你为什么不想使用 mdi 而只想模仿它
  • 在 MDI 中,您的子窗体卡在主窗体的范围内。我需要能够把它们拖出来。

标签: c# .net forms winforms


【解决方案1】:

如果你想模仿 VS 的行为,那么这里有一个方法。

static class Program
{
    static Form _main;
    static Form _previous;

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        // simulate some environment here
        _main = new Form1();
        _main.FormClosed += (s, e) => Application.Exit();
        _main.Show();
        new Form2 { Text = "1" }.Show();
        new Form2 { Text = "2" }.Show();
        new Form2 { Text = "3" }.Show();
        Application.Run();
    }

    public static void MenuOpen(Form form)
    {
        _main.Activate();
        _previous = form;
        _main.MainMenuStrip.MenuDeactivate += MainMenuStrip_MenuDeactivate;
        _main.MainMenuStrip.Show();
    }

    static void MainMenuStrip_MenuDeactivate(object sender, EventArgs e)
    {
        _main.MainMenuStrip.MenuDeactivate -= MainMenuStrip_MenuDeactivate;
        _previous.Activate();
        _previous.Focus();
    }
}

Form1 是任何定义了MainMenuStrip 的表单(又名主表单),当表单关闭时应用程序结束。

Form2 中,您只需要处理菜单按键,一种可能性是预览按键按下事件处理程序(不要忘记设置KeyPreview=true):

void Form2_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 
{
    if (e.Alt)
        Program.MenuOpen(this);
}

演示:

【讨论】:

  • 效果很好。我必须将 ProcessCmdKey 与 VK_MENU 一起使用,因为其他控件会捕获 PreviewKeyDown 事件。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 2014-02-09
相关资源
最近更新 更多