Есть ли событие Form, которое вызывается прямо перед тем, как что-либо будет выведено на экран?

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

ОБНОВИТЬ:

Хорошо, я думаю, вы, ребята, убедили меня. Я буду использовать отдельный поток. Я не знал о BackgroundWorker, и его было очень легко реализовать. Теперь моя форма загружается быстро. И вдруг мои поля со списком заполняются. Но я бы не хотел, чтобы пользователь нажимал на комбинации до того, как они будут заполнены. Каков наилучший/стандартный способ сделать это с помощью Winforms? Есть ли способ отключить события ввода в форме, пока фоновый рабочий не завершится?


person bsh152s    schedule 21.09.2010    source источник
comment
На всякий случай, если вы передумаете использовать отдельный поток: с BackgroundWorker это действительно просто: dotnetperls.com/backgroundworker   -  person Heinzi    schedule 21.09.2010
comment
Вы не можете показывать занятый курсор, пока поток пользовательского интерфейса занят доступом к базе данных. Выполнение подобных операций в фоновом потоке — это то, что позволяет вам создать хороший индикатор выполнения или курсор ожидания.   -  person Adam Lear    schedule 21.09.2010
comment
Я решил использовать фонового рабочего. Но теперь у меня есть дополнительный вопрос. Смотрите мой обновленный вопрос.   -  person bsh152s    schedule 21.09.2010


Ответы (6)


Вы можете попробовать выполнить свои дорогостоящие операции в конструкторе формы, чтобы, когда пришло время показать форму, у нее уже были данные, необходимые для отображения. Также изучите методы SuspendLayout/ResumeLayout.

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

person Adam Lear    schedule 21.09.2010
comment
Я решил использовать BackgroundWorker для обращения к базе данных. Но я все же хотел бы запретить пользователю изменять данные в форме до тех пор, пока работник не завершит работу. Как мне это сделать? Смотрите мой обновленный вопрос для более подробной информации. Спасибо. - person bsh152s; 21.09.2010
comment
Я бы начал с ваших элементов управления в отключенном состоянии (т.е. Enabled = false). И включите их после завершения фоновой операции. - person Adam Lear; 21.09.2010

Я бы порекомендовал вам покрыть форму меткой Loading перед началом загрузки.

person SLaks    schedule 21.09.2010

Вы сможете решить проблему, поместив загрузку в код конструктора перед вызовом IntializeComponent(). На данный момент элементы управления в форме еще не созданы (поскольку это то, что делает InitializeComponent).

Тем не менее, форма также еще не видна в этой фазе. Если вы хотите показать пустую форму, то я думаю, что возможным решением (я не пробовал это, но я думаю, что это должно сработать) будет вызов this.Show() (для отображения формы) и Application.DoEvents(), чтобы позволить WinForms обрабатывать события и отображать форма.

person Tomas Petricek    schedule 21.09.2010
comment
Я согласен, что это самый простой способ. Однако у нас все работает так, что наши компоненты проходят через фабрику классов. Наше приложение изменяется в зависимости от того, какие компоненты установлены, и способ, которым мы выясняем, что он установлен, — это вызов конструктора. Просто пытаюсь работать с тем, что есть. - person bsh152s; 22.09.2010

Я не уверен, поможет это или нет, но событие Move вызывается перед Load.

person D'Arcy Rittich    schedule 21.09.2010

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

В обработчике событий Shown включите песочные часы, выполните свою работу, а затем выключите песочные часы.

person Brad Bruce    schedule 21.09.2010

ComboBox имеет BeginUpdate() и EndUpdate(), которые можно вызывать при добавлении больших объемов данных или медленных данных в элемент управления. SuspendLayout() и 'ResumeLayout()` в форме также могут помочь решить проблемы с перерисовкой.

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

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

person James King    schedule 22.09.2010