【问题标题】:Prevent MainMenu on Windows Form from flickering (redrawing) when multiple sub menu items added?添加多个子菜单项时,防止 Windows 窗体上的 MainMenu 闪烁(重绘)?
【发布时间】:2012-02-04 15:35:38
【问题描述】:

在我的应用程序中,我有一个表单,其中一个顶级菜单项的子菜单项是动态创建的。所以目标是我一直有一个名为“Actions”的顶级菜单项,但子项是动态生成的。我遇到的问题是,对于每个子项目,我都会添加整个 MainMenu 重绘和闪烁。由于我猜测更多的绘画调用而添加的子菜单项越多,问题就越明显,例如,如果我只添加一个子菜单项,它不会经常闪烁,但如果我添加 15 个(其中对我的应用程序来说是典型的)它几乎每次都很明显。请注意,这是使用 MenuItems 而不是 MenuStrip,我们开发了自定义控件来支持 MenuItems,但尚未过渡到使用 MenuStrip。

我创建了一个简单的示例来演示这一点,我只需单击一个按钮即可将 15 个子项添加到每个顶级菜单项(我的演示中有两个“文件”和“编辑”),你会看到它调用“DrawMenuBar”30 次。这是代码在单击按钮时所做的事情:

private void CreateSubMenus()
{
    foreach (MenuItem menu in this.Menu.MenuItems)
    {
        for (int i = 1; i <= 15; i++)
        {
                MenuItem newSubMenu = new MenuItem();
                newSubMenu.Text = "TestSub" + i;
                menu.MenuItems.Add(newSubMenu);
        }
     }
}

无法以新用户身份嵌入图像,但这里有一个指向分析显示的链接Profiling Adding Sub Menus

所以 DrawMenuBar 被调用了 30 次。

我尝试过使用类似的东西:

this.Menu.MenuItems[0].AddRange(

但这最终会导致相同数量的绘图调用。我能想到的最好的方法是从 MainMenu 中删除顶级菜单项,然后进行所需的更改,然后重新链接它,但这看起来也不是很好,因为菜单项消失而不是重新出现。理想情况下,顶级菜单栏的可见性不会闪烁或发生任何变化,因为我没有更改那里的任何内容,而是更改子菜单项。

基本上,看看是否有一种等效的方法来执行暂停/恢复布局,但对于 MainMenu 对象。

【问题讨论】:

    标签: c# winforms menu


    【解决方案1】:

    我看到了。你需要找到一个丑陋的反射黑客来解决这个问题。至少对您的示例代码有效:

            var pi = typeof(MainMenu).GetField("form", BindingFlags.NonPublic | BindingFlags.Instance);
            object form = pi.GetValue(this.Menu);
            pi.SetValue(this.Menu, null); 
            // etc..
            pi.SetValue(this.Menu, form);
    

    也许是时候开始支持 MenuStrip 了。

    【讨论】:

    • 谢谢,这确实有效(在我的实际项目中也试过)。我同意,是时候继续使用 MenuStrip,但我想知道我是否可能遗漏了一些关于如何让闪烁消失的内容。
    【解决方案2】:

    尝试使用SuspendLayout() -> ResumeLayout() 方法调用。在它们中间编写您的菜单项添加代码。顺便说一句,点击链接查看MSDN 上的具体代码示例。

    【讨论】:

    • 抱歉,忘记在我的帖子中说明这一点。基本上是在寻找与 Suspend/Resume Layout 等效的东西,除非它对 MainMenu 或 MenuItem 类不可用。不过,这基本上就是我想要的,能够进行批量更改,而不会每次都触发更改的事件。
    • @RyanR:您应该在 Form 对象上调用该函数,notMenu 上调用。
    • 在表单对象上调用 Suspend/Resume Layout 时仍然会发生重绘。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2011-11-22
    • 2010-11-22
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多