Страницы

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

понедельник, 24 февраля 2020 г.

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

#c_sharp #winforms #opacity


Имеется 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;
}


Может есть у кого простое или не очень решение этой проблемы. Хотелось бы чтобы весь
интерфейс появлялся плавно, а не только форма, и по окончанию мгновенно элементы.
    


Ответы

Ответ 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; - это необходимо, чтобы избежать утечки памяти. При желании, таймер можно создать в дизайнере формы, задав ему необходимые свойства и события.

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

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