Недавно я внес некоторые оптимизации в код. После теста эффект в порядке, но я обнаружил, что интерфейс будет мерцать, в частности, будет мерцать элемент управления TreeView, язык — C#, а IDE — VS2005. Изучив некоторую информацию и применив некоторые базовые методы (например, включение двойной буферизации), я обнаружил, что это не дало никакого эффекта.
Поэтому я воспользовался инструментом PRfiler, чтобы выяснить, что узкое место заключается в операции EndUpdate после каждого обновления интерфейса (это используется для уменьшения количества обновлений интерфейса, но здесь оно не идеально, поскольку в элементе управления много элементов) Я предполагаю, что каждый раз, когда он обновляется, нижний слой .Net Каждый примитив будет обновляться и перерисовываться, поэтому скорость будет низкой и вызывать мерцание. Но в этом случае использование двойной буферизации должно дать лучшие результаты. Еще раз просмотрев код, я обнаружил, что действие обновления может быть слишком частым, поэтому я снизил скорость и стал лучше, но это все равно не сработало.
Продолжайте поиск в Интернете и, наконец, найдите более подходящее решение. Оказывается, базовая перерисовка каждый раз очищает холст, а затем все его перерисовывает. Это основная причина мерцания. Таким образом, функция отправки сообщения перегружается, и это сообщение отключается. Код выглядит следующим образом:
защищенное переопределение void WndProc (ref Message m)
{
if (m.Msg == 0x0014) // Отключаем очистку фоновых сообщений
возвращаться;
base.WndProc(ref m);
}
успех!
Примечание. Двойная буферизация по-прежнему полезна, когда обновления происходят не очень часто и элемент управления не содержит слишком много элементов. Если элементов слишком много, каждое обновление будет занимать много времени. Даже если используется двойная буферизация, проблему мерцания решить невозможно. Лично я считаю, что идеальный метод — в конце отключить и очистить фоновые сообщения.
Приложение: Некоторые записи попыток и неудач.
1) Используйте setStyle
В Интернете сказано, что функция setStyle используется для установки параметров элемента управления, а именно:
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
Последний из этих трех параметров зависит от первого и должен сосуществовать, иначе он будет недействителен. А сама эта функция защищена, поэтому перед ее использованием сначала необходимо унаследовать определенный элемент управления.
Эта цель согласуется с предыдущим правильным решением, которое также отключает очистку фона и включает двойную буферизацию, но требует опции пользовательского рисования, и все рисование выполняется пользователем. Это потребует от вас самостоятельно реализовать всю прорисовку элементов управления, что довольно хлопотно. Таким образом, этот метод не является полностью невозможным, но требует дополнительной работы и не рекомендуется. Я тоже не использовал его.
2) Используйте BeginUpdate и EndUpdate.
Эта пара операций дает лучший эффект в сценариях, где для обновления элементов управления требуются пакетные операции, например при добавлении большого количества узлов в пакетах во время инициализации. Недостаток – невозможность немедленного обновления. Поэтому он не подходит для ситуаций, когда узлы часто обновляются и требуют немедленного отражения в интерфейсе. Если вы используете его и не отключите сообщение о четком интерфейсе, элемент управления будет мерцать, в основном он будет иметь белый фон, а содержимое будет почти невидимым (в зависимости от сложности видео). Поскольку обновления интерфейса завершаются в EndUpdate, слишком большое количество операций приводит к тому, что EndUpdate блокируется на долгое время, и интерфейс сначала очищается, а затем обновляется, в результате чего интерфейс долгое время остается пустым.
3) Используйте опцию ControlStyles.EnableNotifyMessage.
Эффект от этого варианта также соответствует правильному решению. Использование:
SetStyle(ControlStyles.EnableNotifyMessage, true);
защищенное переопределение void onNotifyMessage (Сообщение m)
{
//Записываем сюда код сообщения фильтра
}
Однако реальный эксперимент не показал никакого эффекта, не знаю почему, и я не исследовал его подробно.
-