在我的应用程序中,我有一个表单,对于其中一个顶级菜单项,子菜单项是动态创建的。所以目标是我总是有一个名为“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对象。
答案 0 :(得分:0)
尝试使用SuspendLayout() -> ResumeLayout()方法调用。在它们中间写下添加代码的菜单项。顺便说一句,请点击链接查看MSDN
上的具体代码示例。
答案 1 :(得分:0)
我明白了。你需要找到一个丑陋的反思黑客来解决这个问题。这很有用,至少可以使用您的示例代码:
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。