Страницы

Поиск по вопросам

четверг, 2 мая 2019 г.

При восстановлении размера формы, элементы грузятся вконце

Имеется 2 формы, одна из которых является формой заполненной одной картинкой (Form3), вторая (Form1) - мейн. При нажатии на кнопку в Form1 - мейн сворачивается таким образом, открывая F3:
Form3 formButton = new Form3(); formButton.Owner = this; formButton.Show(); formButton.Opacity = 0; while (this.Opacity != 0) { Thread.Sleep(30); this.Opacity -= 0.1; }
while (formButton.Opacity != 1) { Thread.Sleep(30); formButton.Opacity += 0.1; }
Проблема в том, что при появлении, пока выполняется цикл, на форме нет ничего, кроме дырок от элементов. Сами элементы загружаются только когда программа выходит из цикла.
Вот обратное возвращение мейна:
formMain.Opacity = 0; formMain.Show(); while (formMain.Opacity != 1) { Thread.Sleep(30); formMain.Opacity += 0.1; } while (this.Opacity != 0) { Thread.Sleep(30); this.Opacity -= 0.1; }
Может есть у кого простое или не очень решение этой проблемы. Хотелось бы чтобы весь интерфейс появлялся плавно, а не только форма, и по окончанию мгновенно элементы.


Ответ

Как уже сказано в комментариях, циклы while c Thread.Sleep внутри работают в потоке GUI, что приводит к "замерзанию" формы.
Давайте сделаем это с помощью таймера.
Таймеров в дотнете имеется несколько штук разных, нам понадобится тот, который в пространстве имён System.Windows.Forms.Timer - он может работать с контролами на форме напрямую, так как его событие Tick вызывается в том же потоке.
Добавьте в класс вашей основной формы два поля:
System.Windows.Forms.Timer timer; Form3 formButton;
И обработчик события таймера:
private void Timer_Tick(object sender, EventArgs e) { if (Opacity > 0) this.Opacity -= 0.1; else if (formButton.Opacity < 1) formButton.Opacity += 0.1; else { timer.Stop(); timer.Tick -= Timer_Tick; } }
Теперь ваш код будет выглядеть следующим образом:
formButton = new Form3(); formButton.Owner = this; formButton.Show(); formButton.Opacity = 0;
timer = new System.Windows.Forms.Timer(); timer.Interval = 30; timer.Tick += Timer_Tick; timer.Start();
Обратите внимание, что свойство Opacity формы имеет тип double. Поэтому я заменил точные сравнения != 0 и != 1 на > 0 и < 1 - это связано со спецификой представления вещественных чисел - точное сравнение может не сработать.
Также обратите внимание на необходимость отписки таймера от события: timer.Tick -= Timer_Tick; - это необходимо, чтобы избежать утечки памяти.
При желании, таймер можно создать в дизайнере формы, задав ему необходимые свойства и события.

Комментариев нет:

Отправить комментарий