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