Предотвратить мерцание (перерисовку) MainMenu в форме Windows при добавлении нескольких элементов подменю? - PullRequest
0 голосов
/ 07 января 2012

В моем приложении есть Форма, в которой для одного из пунктов меню верхнего уровня элементы подменю создаются динамически. Итак, цель в том, чтобы у меня всегда был пункт меню верхнего уровня, называемый «Действия», но подэлементы генерируются динамически. У меня проблема в том, что для каждого подэлемента я добавляю все перекрашивания и мерцания 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);
        }
     }
}

Невозможно вставить изображения как нового пользователя, но вот ссылка на то, что показывает профилирование Профилирование Добавление подменю

Итак, DrawMenuBar вызывается 30 раз.

Я пытался использовать что-то вроде:

this.Menu.MenuItems[0].AddRange(

но это приводит к тому же количеству вызовов. Лучшее, что я могу придумать, - это удалить элемент меню верхнего уровня из MainMenu, затем внести необходимые изменения, затем заново связать его, но это также не выглядит так здорово, потому что пункт меню исчезает, а затем появляется снова. В идеале не должно быть мерцания или каких-либо изменений в видимости строки меню верхнего уровня, поскольку я ничего там не изменяю, а только пункты подменю.

В основном, ищем эквивалентный способ сделать макет Suspend / Resume, но для объекта MainMenu.

Ответы [ 2 ]

0 голосов
/ 07 января 2012

Я вижу это. Вам нужно будет найти уродливое отражение, чтобы обойти это. Это сработало, по крайней мере, с вашим примером кода:

        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 возможно.

0 голосов
/ 07 января 2012

Попробуйте использовать SuspendLayout () -> ResumeLayout () вызовы методов. В середине их напишите пункты меню, добавив код. Кстати, перейдите по ссылке, чтобы увидеть конкретный пример кода на MSDN.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...