我发现当我有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%
}
根据我使用的性能分析器,cm.IsOpen占用大部分时间 - 但设置mi.Header也很重要。
答案 0 :(得分:7)
在一个级别上拥有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;