将Form.Owner设置为来自不同线程的表单 [英] Setting Form.Owner to a form from a different thread

查看:209
本文介绍了将Form.Owner设置为来自不同线程的表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序(C#,VS2008)通过网络从数据库(SQL Server 2008 Express)加载信息。在(可能)较长时间的等待期间,我希望有一个加载...对话框出现在另一个线程上,但只有当操作超过特定时间段(比如说500毫秒)时才会出现。

因此,到目前为止,我没有设置加载对话框窗体的所有者(即调用LoadingDialog.ShowDialog())后500ms后显示加载窗体(如果操作持续很长时间) ()),但是当我尝试调用LoadingDialog.ShowDialog(IWin32Window所有者)并将owner设置为主窗体(通过线程的参数传入)时,我得到关于跨线程访问控件的InvalidOperationException。

我的基本问题是:我可以创建ShowDialog表单并将owner参数设置为另一个线程上的表单吗?我想这样做,以便加载对话框是模态的应用程序的其余部分,即像任何其他对话框采取的焦点,并禁止输入其他地方。

任何人都可以提供一个建议?我已经阅读了关于启动屏幕的堆,但没有运气,关于Invoke和BeginInvoke也没有运气。是否有不同的方式我应该去做这件事?



如果您不明白,请随时要求澄清。



Merci(正如他们在法语中所说),

雅各布。

解决方案

你应该在后台线程中运行你的长进程,然后将你的Loading ...表单显示为非模态对话框。这样,用户可以看到加载指示,但仍然与系统的其他部分进行交互。

另一种选择是显示加载进度状态栏或类似的。关键是确保长操作在后台线程上完成,并且所有GUI逻辑都在GUI线程上完成。



一个好的线程格式可能看起来像(这只是用于演示目的的伪代码 - 您需要使用Invoke来获得适当的线程):

  RunInBackground(DoLongOperation); 
ShowLoadingDialog();
...

DoLongOperation()
{
LongOperation();
RunOnGUI(FinishLongOperation);


FinishLongOperation()
{
CloseLoadingDialog();
}


My application (C#, VS2008) loads information from a database (SQL Server 2008 Express) over the network. During (possibly) longish waits, I want to have a 'Loading...' dialog box appear running on a different thread, but only if the operation takes more than a specific time period (say 500ms).

So, I have so far got my loading form being displayed after 500ms (if the operation lasts that long) without setting the loading dialog form's owner (i.e calling LoadingDialog.ShowDialog()), but when I try to call LoadingDialog.ShowDialog(IWin32Window owner) with owner set to the main form (passed in through the thread's parameter) I get the InvalidOperationException about accessing controls across threads.

My basic question is: Can I create and ShowDialog a form with the owner parameter set to a form on another thread? I want to do this so that the loading dialog is modal the rest of the application, i.e. like any other dialog takes the focus and disallows input elsewhere.

Can anyone offer a suggestion? I have read heaps about splash screens with no luck, also about Invoke and BeginInvoke with no luck. Is there a different way I should go about this?

Please feel free to ask for clarification if you don't understand.

Merci (as they say in French),

Jacob.

解决方案

You should run your long process in a background thread, and then show your Loading... form as a non-modal dialog. That way, the user can see the Loading indication, but still interact with other parts of the system while its going on.

Another option would be to show the loading progress in a status bar or similar. The key is to make sure the long operation is done on a background thread and all the GUI logic is done on the GUI thread.

A good threading format might look like (this is just pseudocode for demonstration purposes - you need to use Invoke to get the appropriate threading):

RunInBackground(DoLongOperation);
ShowLoadingDialog();
...

DoLongOperation()
{
    LongOperation();
    RunOnGUI(FinishLongOperation);
}

FinishLongOperation()
{
   CloseLoadingDialog();
}

这篇关于将Form.Owner设置为来自不同线程的表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆