且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

父窗体正在给前面的子窗体菜单条被点击时

更新时间:2023-12-01 22:41:04

这是被引入.NET 4.5 pretty的讨厌的错误。知识库文章是可在这里。解决方法是目前仅可作为一个修补程序,希望这将使它成为一个服务的更新很快。我只是复制/粘贴说明:

  

假设你有一个.NET框架4.5的Windows窗体应用程序。当您单击菜单项来打开应用程序中的一个子窗口,通过菜单和子窗口交互出现错误的行为。

     

例如,您可能会遇到以下情况:

     

在打开的子窗口的上下文菜单,主窗口中把焦点。
     不能使用助记符来访问菜单项。

     

出现此问题的原因IMessageFilter接口脱钩太积极。因此,在.NET Framework 4.5不滤镜菜单中相关的窗口消息。


更新:这个问题是固定在发布了1月8日在.NET 4.5的更新,2013年知识库文章在这里

I have a pretty strange but reproductible problem.

I have a MenuStrip which can open a new Modeless form with the Form.Show() method.

The child form also have a Menu Strip.

The strange stuff happens when you start by clicking the menu strip of the child form. Then the parent form is coming back foreground and saying hello. That's a real pain.

How to prevent this problem?

A Scorcese movie to illustrate my problem by following this link zippyshare.com (3Mo)

As you can see in the video, parent form doesn't take focus, it is just bringed front by somehing else.

Note that repacing the MenuStrip by a ToolStrip correct the problem.

Some Code to reproduce the problem:

public class DemoLostfocus : Form
{
    private void InitializeComponent()
    {
        this.menuStrip1 = new MenuStrip();
        this.fileToolStripMenuItem = new ToolStripMenuItem();
        this.openModelessFormToolStripMenuItem = new ToolStripMenuItem();
        this.menuStrip1.SuspendLayout();
        this.SuspendLayout();

        this.menuStrip1.Items.AddRange(new ToolStripItem[] {
        this.fileToolStripMenuItem});
        this.menuStrip1.Location = new System.Drawing.Point(0, 0);
        this.menuStrip1.Name = "menuStrip1";
        this.menuStrip1.Size = new System.Drawing.Size(284, 24);
        this.menuStrip1.TabIndex = 0;
        this.menuStrip1.Text = "menuStrip1";

        this.fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] {
        this.openModelessFormToolStripMenuItem});
        this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
        this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
        this.fileToolStripMenuItem.Text = "File";

        this.openModelessFormToolStripMenuItem.Name = "openModelessFormToolStripMenuItem";
        this.openModelessFormToolStripMenuItem.Size = new System.Drawing.Size(187, 22);
        this.openModelessFormToolStripMenuItem.Text = "Open Modeless Form";
        this.openModelessFormToolStripMenuItem.Click += new System.EventHandler(this.openModelessFormToolStripMenuItem_Click);

        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(284, 262);
        this.Controls.Add(this.menuStrip1);
        this.MainMenuStrip = this.menuStrip1;
        this.Name = "DemoLostfocus";
        this.Text = "DemoLostfocus";
        this.menuStrip1.ResumeLayout(false);
        this.menuStrip1.PerformLayout();
        this.ResumeLayout(false);
        this.PerformLayout();
    }

    private MenuStrip menuStrip1;
    private ToolStripMenuItem fileToolStripMenuItem;
    private ToolStripMenuItem openModelessFormToolStripMenuItem;

    public DemoLostfocus()
    {
        InitializeComponent();
    }

    private void openModelessFormToolStripMenuItem_Click(object sender, EventArgs e)
    {
        (new DemoLostfocus()).Show();
    }
}

This is a pretty nasty bug that was introduced in .NET 4.5. The KB article is available here. The fix is right now only available as a hotfix, hopefully it will make it into a service update soon. I'll just copy/paste the description:

Assume that you have a .NET Framework 4.5-based Windows Form application. When you click a menu item to open a child window in the application, interactions with the menu and child window behave incorrectly.

For example, you may experience the following:

When you open a context menu in the child window, the main window takes the focus.
You cannot use mnemonics to access a menu item.

This issue occurs because the IMessageFilter interface is unhooked too aggressively. Therefore, the .NET Framework 4.5 does not filter menu-related window messages.


Update: this issue was fixed in a .NET 4.5 update released on Jan 8th, 2013. The KB article is here.