Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当添加多个子菜单项时,是否防止Windows窗体上的主菜单闪烁(重画)?_C#_Winforms_Menu - Fatal编程技术网

C# 当添加多个子菜单项时,是否防止Windows窗体上的主菜单闪烁(重画)?

C# 当添加多个子菜单项时,是否防止Windows窗体上的主菜单闪烁(重画)?,c#,winforms,menu,C#,Winforms,Menu,在我的应用程序中,我有一个表单,其中一个顶级菜单项的子菜单项是动态创建的。因此,我的目标是始终有一个名为“Actions”的顶级菜单项,但子项是动态生成的。我遇到的问题是,对于每个子项,我都会添加整个主菜单重绘和闪烁。问题更为明显的是,由于我猜测的更多绘制调用而添加的子菜单项越多,例如,如果我只添加一个子菜单项,它不会经常闪烁,但如果我添加15个(这对于我的应用程序来说是典型的),它几乎每次都很明显。请注意,这是使用MenuItems而不是MenuStrip,我们开发了自定义控件来支持MenuI

在我的应用程序中,我有一个表单,其中一个顶级菜单项的子菜单项是动态创建的。因此,我的目标是始终有一个名为“Actions”的顶级菜单项,但子项是动态生成的。我遇到的问题是,对于每个子项,我都会添加整个主菜单重绘和闪烁。问题更为明显的是,由于我猜测的更多绘制调用而添加的子菜单项越多,例如,如果我只添加一个子菜单项,它不会经常闪烁,但如果我添加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);
        }
     }
}
但这最终会导致相同数量的draw调用。我能想到的最好办法是从主菜单中删除顶级菜单项,然后进行所需的更改,然后重新链接,但这看起来也不太好,因为菜单项消失后又重新出现。理想情况下,顶层菜单栏的可见性不会出现闪烁或任何更改,因为我不会在那里更改任何内容,而是更改子菜单项


基本上,看看除了MainMenu对象之外,是否有一种等效的方法来执行挂起/恢复布局。

尝试使用方法调用。在中间写上你的菜单项添加代码。顺便说一下,按照链接查看
MSDN
上的具体代码示例

我看到了。你需要一个丑陋的反射黑客来解决这个问题。至少在您的示例代码中是这样:

        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了。

对不起,我忘了在我的帖子中澄清这一点。基本上是寻找与挂起/恢复布局等效的布局,但它不适用于MainMenu或MenuItem类。这正是我所希望的,能够在每次都不触发更改事件的情况下进行批量更改。@RyanR:您应该在
表单
对象上调用该函数,而不是在
菜单
上。在表单对象上调用挂起/恢复布局时仍会重新绘制。谢谢,这确实有效(在我的实际项目中也尝试过)我同意,是时候转到MenuStrip了,但我想知道我是否只是错过了一些关于如何消除闪烁的东西。
        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);