形式加载时组合框的延迟加载

时间:2009-11-11 15:52:30

标签: c# winforms

我有一个带有多个组合框/列表框等​​的Windows窗体(C#)项目,这些项目在表单加载时会填充。

问题是组合框/列表框的加载速度很慢,并且由于在表单尝试显示时完成加载,因此在填充所有控件之前不会显示整个表单。在某些情况下,这可能超过20秒。

如果有一个Form_finished_loaded类型的事件,我可以把我的代码放在那里,但是我无法找到在完成表单绘制基本控件后触发的事件。

我有一个要求 - 加载必须在主线程中完成(因为我从非线程友好的COM应用程序中获取项目)。

我找到了一个可能的解决方案,但也许有更好的方法? 我可以在创建表单时创建一个System.Timer.Timer,并在大约1秒后调用第一个Tick,然后从该tick中填充列表。这使表单在开始填充列表之前有足够的时间显示。

有没有人有关于如何延迟加载控件的其他提示?

6 个答案:

答案 0 :(得分:6)

首次显示表单时会出现Shown event。“此外,您可能希望使用BeginUpdate and EndUpdate函数来更快地填充组合框。

答案 1 :(得分:1)

它具有某种解决方法的气味,但这种方法应该满足您的需求:

private bool _hasInitialized = false;
private void Form1_Shown(object sender, EventArgs e)
{    
    if (!_hasInitialized)
    {
        ThreadPool.QueueUserWorkItem(state =>
        {
            Thread.Sleep(200); // brief sleep to allow the main thread
                               // to paint the form nicely
            this.Invoke((Action)delegate { LoadData(); });    
        });
    }
}

private void LoadData()
{
    // do the data loading
    _hasInitialized = true;
}

它的作用是它在显示表单时做出反应,检查它之前是否已经初始化,如果没有,它会在主线程上调用LoadData方法之前产生一个等待片刻的线程。这将允许表格正确绘制。通过简单地调用this.Refresh()也许可以实现同样的目标,但我喜欢让系统决定如何开展工作的想法。

我仍然会尝试将数据加载到工作线程上,调用主线程来填充UI(如果它完全可以使用COM组件)。

答案 2 :(得分:0)

您可以从调用COM组件的Web服务获取数据吗?

这样,您可以在开始时在Locked表单上显示空控件,进行异步调用以获取数据,并在返回时填充相应的组合,并且一旦加载了所有组合,您就可以解锁表单用户使用。

答案 3 :(得分:0)

您可以监听VisibleChanged事件,并且第一次将值设置为true时,您可以放置​​初始化代码。

答案 4 :(得分:0)

FormShown不是您正在寻找的活动吗?

答案 5 :(得分:0)

当你说由于COM你不能使用后台线程时你是什么意思?我在我的应用程序中使用了许多COM组件,并在后台线程上运行它们。

如果您创建一个新线程作为STAThread,您可以在非UI线程上加载ComboBox / ListBox。 IIRC ThreadPool将工作线程分配为MTAThread,因此您需要手动创建线程而不是使用ThreadPool.QueueUserWorkItem。