我正在撰写表单应用程序。我正在添加一个允许您双击datagridview控件的行以打开包含更多详细信息的新表单的部分。这些额外的细节是从数据库中提取的,这需要一些时间才能完成。
如果我从表单的load事件运行数据库查询,则表单不会显示,直到load事件中的所有内容都完成,这可能需要几秒钟。
我希望双击时立即显示表单,并在数据准备好后填写所有字段。
我应该使用除Load之外的其他事件吗?
答案 0 :(得分:1)
实现此目的的标准方法是使用background worker thread并禁用按钮,直到工作线程完成。您可以在后台工作人员上订阅完整的活动。
答案 1 :(得分:0)
你应该使用线程。启动一个线程,在表单的load事件中进行数据检索。 Introduction to threading
答案 2 :(得分:0)
您应该使用BackgroundWorker
在后台线程中加载数据,而不会冻结UI。
如果您真的想加载UI线程,则应该处理Shown
事件。
答案 3 :(得分:0)
这是一个使用BackgroundWorker
的c#示例,因为其他帖子提到了从.xml
文件加载单位定义,并在完成后更改状态标签。我坚持使用表单初始化程序,但最好是在OnLoad()
覆盖中启动它。
public MainForm()
{
InitializeComponent();
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = false;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
unitsToolStripLabel.Text = "Loading Units";
bw.RunWorkerAsync();
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
...
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
unitsToolStripLabel.Text = string.Format("{0} Units Loaded", Units.UnitLibrary.WorkingSet.Count);
unitsToolStripLabel.LinkBehavior = LinkBehavior.HoverUnderline;
unitsToolStripLabel.Click += new EventHandler(unitsToolStripLabel_Click);
}
请详细解释为什么你不想使用线程/后台工作者?
答案 4 :(得分:0)
虽然正确的方法是BackgroundWorker线程,但快速而脏的方法是在Load事件上启动计时器并在计时器到期时获取数据。假设10ms足以绘制表单,那么您可以在获取数据时禁用控件并将光标设置为忙。但是,当数据库忙于导致重新绘制工件时,这仍然会锁定UI线程,例如,如果窗口的一部分被覆盖,并且不允许您使用进度条显示进度。
答案 5 :(得分:0)
您可以让load事件完成,然后启动另一种方法从数据库中提取数据。可以在表单完成加载后完成UI的初始化,但要确保在初始化时禁用UI控件。