C# 是否有一个表单事件在任何东西被绘制到屏幕之前被调用?

C# 是否有一个表单事件在任何东西被绘制到屏幕之前被调用?,c#,winforms,onload-event,C#,Winforms,Onload Event,我已尝试重写OnLoad事件,但在该方法完成之前,表单已被绘制。我正在调用base.OnLoad方法。但是,表单在事件期间部分绘制(可以看到工件)。我注意到这一点,因为我正在访问数据库,这需要一些时间。在这种情况下,我将获取一些数据并将其绑定到表单的控件。请不要告诉我使用单独的线程。为了简单起见,我宁愿在加载数据时显示一个忙碌的光标 更新: 好吧,我想你们说服了我。我将使用单独的线程。我不知道BackgroundWorker,它很容易实现。现在我的表单正在快速加载。然后,我的组合框突然被填充了。

我已尝试重写OnLoad事件,但在该方法完成之前,表单已被绘制。我正在调用base.OnLoad方法。但是,表单在事件期间部分绘制(可以看到工件)。我注意到这一点,因为我正在访问数据库,这需要一些时间。在这种情况下,我将获取一些数据并将其绑定到表单的控件。请不要告诉我使用单独的线程。为了简单起见,我宁愿在加载数据时显示一个忙碌的光标

更新:


好吧,我想你们说服了我。我将使用单独的线程。我不知道BackgroundWorker,它很容易实现。现在我的表单正在快速加载。然后,我的组合框突然被填充了。但是,我想防止用户在填充组合之前单击组合。使用Winforms执行此操作的最佳方式/标准方式是什么?有没有办法在后台工作程序完成之前关闭表单中的输入事件?

我建议您在开始加载前在表单上盖上一个
加载标签。

我不确定这是否有帮助,但是
移动
事件是在
加载

之前调用的,您可以尝试在表单的构造函数中执行代价高昂的操作,以便在显示表单时,它已经拥有了需要呈现的数据。还可以查看
SuspendLayout
/
resumeloayout
方法


但是这些解决方案都不如使用不同的线程来执行昂贵的操作那么优雅。

您应该能够通过在调用
initializeComponent()
之前将加载放在构造函数代码中来解决问题。此时,表单上的控件尚未创建(因为这是
InitializeComponent
所做的)


然而,在这一阶段,该表单还不可见。如果您想显示一个空白表单,那么我认为一个可能的解决方案(我没有尝试过,但我认为它应该可以工作)是调用
this.show()
(显示表单)和
Application.DoEvents()
,让WinForms处理事件并显示表单。

显示的事件对这一点很有好处。表单将完全显示,然后触发显示的事件。这将为用户提供一个干净的屏幕,在加载数据时不会部分绘制字段


在显示的事件处理程序中,打开沙漏,完成工作,然后关闭沙漏。

组合框
具有一个
BeginUpdate()
EndUpdate()
,在向控件添加大量数据或慢速数据时可以调用该函数<表单上的code>SuspendLayout()和'ResumeLayout()`也可能有助于解决您的重画问题

如果您只想阻止用户单击该控件,还可以禁用该控件。如果禁用表单本身,则所有包含的控件也将被禁用


如果您使用的是后台线程,则必须确保在启动线程之前从主UI线程调用这些线程,并在后台工作程序完成后再次从主UI线程调用这些线程。

以防您改变主意使用单独的线程:使用BackgroundWorker,这真的很简单:当UI线程忙于访问数据库时,不能显示忙碌的光标。在后台线程上运行这样的操作使您能够设置一个好的进度条或等待光标。但现在我有一个后续问题。请参阅我更新的问题。我已决定使用BackgroundWorker进行数据库访问。但是,我仍然希望阻止用户在工作完成之前修改表单上的数据。我该怎么办?有关更多详细信息,请参阅我更新的问题。谢谢。我会从你的控件处于禁用状态开始(即Enabled=false)。我同意这是最简单的方法。然而,我们工作的方式是我们的组件通过一个“类工厂”。我们的应用程序会根据安装的组件和我们确定安装的方式进行更改,方法是调用构造函数。只是试着用我所拥有的来工作。