Как исправить вложенные проблемы управления флеш-памятью winform

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

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

Я попытался использовать методы Control.SuspendLayout/Control.ResumeLayout во многих разных местах и ​​способами, и я не могу устранить безумное мерцание. Я думал, что приостановление макета корневого элемента управления во время изменений устранит проблему, но кажется, что этот SuspendLayout не помогает при изменении дочерних элементов управления.

Нужно ли использовать другой подход, а не SuspendLayout? Есть ли способ отлаживать SuspendLayout, чтобы понять, почему он не каскадирует все дочерние элементы управления?

Ответ 1

Приостановка/ResumeLayout не является вашей проблемой здесь. Это только приостанавливает автоматическую компоновку, тип, вызванный свойствами Якоря и Дока. Двойная буферизация также не может решить вашу проблему, которая только подавляет мерцание в каждом отдельном элементе управления. Ваша настоящая проблема заключается в том, что вы одновременно обновляете слишком много элементов управления, каждый из которых будет рисовать сам, и это требует времени.

Что вам нужно, это другой тип двойной буферизации, композитинг. Проверьте, разрешает ли решение в этот поток.

Ответ 2

В дополнение к предложению @tommieb75 для двойной буферизации вы можете попробовать и посмотреть, есть ли у ваших регуляторов уровня корня пары методов BeginUpdate/EndUpdate. Они должны помочь подавлять репликации между вызовами.

Ответ 3

Используйте SetControlStyles в пользовательском элементе управления, флаг OptimizedDoubleBuffer, который предотвратит мерцание.

Ответ 4

Если вы используете WinForms 2+, тогда вы можете просто установить свойство DoubleBuffer 'для элемента управления в true ( в дизайнере даже).

С фреймворком 2 установка DoubleBuffered устанавливает три флага: OptimizedDoubleBuffer, AllPaintingInWmPaint, и еще один, который я забыл, возможно, "UserPaint".

Кроме того, посмотрите на BeginUpdate/EndUpdate, как указано @yetapb.