Как предотвратить перерисовку пользовательского интерфейса каждого элемента управления один за другим - PullRequest
3 голосов
/ 22 сентября 2011

В моем пользовательском контроле я выполняю длительную операцию. Чтобы пользователи не могли щелкнуть пользовательский интерфейс, я показываю индикатор выполнения и отключаю весь пользовательский интерфейс, например:

this.Enabled = false;
ShowProgressBar();
DoLengthyOperation();
RemoveProgressBar();
this.Enabled = true;

Это работает нормально. Однако у моего пользовательского элемента управления есть много других элементов управления, в которых также есть элементы управления, внутри которых также есть элементы управления, и т. Д.

this.Enabled = false 

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

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

Надеюсь, это не глупый вопрос;)

Не знаю, относится ли это к делу: мои элементы управления получены из DevExpress.XtraEditors.XtraUserControl.

Ответы [ 5 ]

3 голосов
/ 22 сентября 2011

Вы пробовали Form.SuspendLayout и Form.ResumeLayout?Кажется, что вам нужно.Более подробную информацию о сайте msdn можно найти здесь .

Вы вызываете suspendlayout, прежде чем захотите перерисовать, а затем возобновите работу после отключения всех элементов управления.1007 * Если в форме есть индикатор выполнения, вам придется «показать» его, прежде чем приостановить макет.Извините, я пропустил это.

3 голосов
/ 22 сентября 2011

попробуйте это:

this.Invalidate();  // Invalidate the whole window
this.Enabled = false;
this.Refresh(); // Redraw every invalidated part of the window, so everything
2 голосов
/ 23 сентября 2011

Кажется, что ни одно из предложенных решений не работает.

Я думаю, что часть проблемы заключается в том, что я использую DevExpress, и каждый элемент управления не содержит непосредственно свой субконтроль, а использует LayoutControlGroups, LayoutControls, панели и т. Д. Таким образом, фактическое количество используемых элементов управления намного выше, чем фактические элементы управления, которые вы используете. см. на экране, и это должно быть отключено.

Так что я просто добавил свою собственную рекурсивную функцию, которая отключает только элементы управления определенных типов, в моем случае кнопки и поля редактирования. Остальное просто игнорируется. Это не только намного быстрее, но и выглядит намного лучше. Больше никаких мерцаний.

Я думаю, что собираюсь использовать это решение, но я ценю усилия всех, кто разместил здесь ответ или комментарий, спасибо!

Теперь я вижу, что мой вопрос, кажется, дублирует этот вопрос: Как приостановить рисование для элемента управления и его дочерних элементов? Не пробовал это решение жестко.

1 голос
/ 22 сентября 2011

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

System.Reflection.PropertyInfo aProp =
        typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered",
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Instance);
 aProp.SetValue(YourControlNameHere, true, null);

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

0 голосов
/ 29 октября 2018

Вы можете поместить элементы управления в контейнер (назовите его groupControls), Повернуть свойство visible контейнера на false, (отобразить заставку или контейнер эквивалентного размера с «обновлением» или что-либо еще видимым - назовите его groupUpdateSplash) обновить ваши элементы управленияотключить видимый всплеск контейнера и включить видимый контейнер управления

groupControls.visible = false
groupUpdateSplash.visible = true
/* update controls and everything */
groupUpdateSplash.visible = false
groupControls.visible = true
...