在线程中如何操作Form上的控件

来源:互联网 发布:苹果笔记本安装软件 编辑:程序博客网 时间:2024/05/22 00:41

.NET C#, Application,

这两天在做一个登录界面。

需求:

1。当点击登录按钮后,显示一个进度条,登录按钮上显示的内容变为取消。

2。在收到登录应答后,结束该进度条。

3。在收到登录应答前,用户可以点击取消按钮用来取消登录的动作。

 

V1.0  最初的设想是登录按钮的Click事件处理中产生一个线程来显示进度条,click事件启动该线程,然后执行登录操作,收到登录的应答后结束控制进度条的线程。进行调试时,报错:不能在线程中操作不是在本线程中创建的控制。

    看来此路不通。

V2.0  查看关于Message的帮助,试图通过MessageWindow来发送消息。发现MessageWindow在WindowsCE这个namespace中,于是放弃该思路。

V3.0  在登录界面上增加了一个Timer来控制进度条的显示。在登录按钮的Click事件中启动此Timer,然后调用登录的过程。结果测试时发现进度条永远显示不出来。思索一番后笑自己好傻好天真:因为消息处理是一条一条的处理的,登录按钮的Click事件没有处理完,Windows不会去做别的事情。

V4.0  再试试EventHandler. 将登录的操作放到线程里进行,在Form上增加一个处理登录结束的Event处理方式。在线程取得Server的应答后,该线程调用form的EventHandler。一开始看起来思路是对的,但与V1.0犯了相同的错误:在一个线程中操作另一个线程创建的控件。

V5.0  该怎么办呢?操作控件只能在创建该控件的线程上进行。在CSDN上问了一下,有高手指点查查InvokerRequired的帮助。查到了BeginInvoke,该方法提供了在创建控件的基础句柄所在线程上异步执行指定委托的能力。又在帮助中查到了"如果:使用后台线程搜索文件"这篇文档。

    这样,解决方案就出来了。

 

 

form

{

  1. form{
  2.  private EventHandler onLoginThread;
  3. private void form_Load(..)
  4. {
  5.  onLoginThread = new EventHandler(login_LoginEvent);
  6. }
  7. private void login_LoginEvent(..)
  8. {
  9.    //stop timer
  10.    //control ProgressBasr
  11.    // some other opertion...
  12. }
  13. private void loginButton_Click(..)
  14. {
  15.   // if do login:
  16.   //begin timer
  17.   
  18.   //begin login thread
  19.   tl = new Thread(loginThread);
  20.   // else do cancel
  21. }
  22. private void loginThread()
  23. {
  24.     //connect to server
  25.     ...
  26.     BeginInvoke(onLoginThread);    
  27. }
  28. }

}

 

原创粉丝点击