Lan*_*nce 3 c# wpf contextmenu
我发现当我有10,000个项目时,上下文菜单需要超过10秒才能显示,我想让它更快(例如不到1秒)
这是我的测试代码直接显示上下文菜单的慢度:
private void button1_Click(object sender, RoutedEventArgs e)
{
ContextMenu cm = new ContextMenu();
for (int i = 0; i < 1000; i++)
{
MenuItem mi = new MenuItem();
mi.Header = "test"; // this is HOT - 3%
mi.Tag = this; // cold
for (int j = 0; j < 10; j++)
{
MenuItem mi2 = new MenuItem(); // this is HOT - 1%
mi2.Header = "test"; // this is HOT - 12%
mi2.Tag = this; // cold
mi.Items.Add(mi2); // this is HOT - 6%
}
cm.Items.Add(mi); // this is HOT - 3%
}
cm.IsOpen = true; // this is HOT - 72%
}
Run Code Online (Sandbox Code Playgroud)
根据我使用的性能分析器,cm.IsOpen占用了大部分时间 - 但设置mi.Header也很重要.
这将是一个糟糕的用户体验,在一个级别上拥有1k项目,但是如何制作具有更多\昂贵项目的上下文菜单更具响应性,这是一个公平的问题.
我使用的一般模式是最初使用虚拟子菜单创建我的菜单.虚拟子菜单有一个占位符菜单项,我挂钩子菜单打开事件.在事件处理程序中,我删除了占位符菜单项并添加了实际项目.
此模式允许按需创建子菜单,并且只有在实际打开子菜单时才能创建子菜单.换句话说,它使您的菜单动态化意味着您不必预先创建所有内容,也不必创建数百个不会打开的子菜单.
对于上面的示例,此模式会将初始菜单项数从10k项减少到1k.这应该会让你减少到1秒钟.
在根目录中,根目录中有1k的10k菜单项几乎无法使用.我希望这只是一个思想实验!:)
例
ContextMenu cm = new ContextMenu();
for (int i = 0; i < 1000; i++)
{
MenuItem mi = new MenuItem();
mi.Header = "test";
mi.Tag = this;
object dummySub = new object();
mi.Items.Add(dummySub);
cm.Items.Add(mi);
mi.SubmenuOpened += delegate
{
mi.Items.Clear();
for (int j = 0; j < 10; j++)
{
MenuItem mi2 = new MenuItem();
mi2.Header = "test";
mi2.Tag = this;
mi.Items.Add(mi2);
}
};
}
cm.IsOpen = true;
Run Code Online (Sandbox Code Playgroud)