none
loading窗口怎么关闭? RRS feed

  • 问题

  •   想做一个类似大型程序loading时的窗口.不过用途是在执行较长任务的时候,提示用户等待.类似windows在忙碌的时候鼠标出现滚动沙漏这样的效果.
      思路是这样的:在主界面load的时候打开一个modal子窗口(用form.ShowDialog),然后在启动过程initialsomething()完成后,再将modal窗口关闭(用form.close).
      initialsomething()内部是一个循环,要耗费十几秒钟的时间,就是想让用户在这期间看到modal提示窗口,让用户耐性等待.
      但是现在发现在form.showdialog之后,主线程似乎一直在等待子窗口的退出.我想到了用多线程调用,但是不管是用thread.start或者是invoke方法都提示签名不符,不知道哪里出了问题??
    2009年8月24日 15:06

答案

  • 几个概念一定要清晰

    1  模态窗口肯定会造成线程阻塞  除非你的任务是在后台线程处理的  

    2  独占包括两个方面 
       a 保持在parentwindow  前方  这个只需要设置他的owner   formChild.show (formParent) 就可以了
       b 在他存在的时候 不允许对后面窗体做任何操作  

    所以说 窗体的独占根本不需要模态
    答案破千 马上就要到5星用户了 嘿嘿~~
    • 已标记为答案 picat 2009年8月25日 4:04
    2009年8月25日 3:50

全部回复

  • 不妨试试使用一个txt或是其他文件来操作,而将Loding窗口做成单独的exe,Loading用Process.Start启动主程序,当主程序全部载入完毕时,向txt文件写入某值.当Loading程序通过FileSystemWatch检查到该txt文件被更改,则判定为主程序已经载入完毕,自动结束Loading.exe进程.


    虽然不是专业,努力学.
    2009年8月24日 15:49
  •    你好:
       这是个办法,不过有一个问题,我之所以用form.showdialog方法而不用form.show,就是想让这个提示窗口独占,因为initialsomething()运行的时候不希望有别的操作.这种方式应该跟loading窗口一样,不知道怎么实现的.
    2009年8月25日 2:21
  • 你好!
         可以试试使用form.Show()方法,这个不会阻塞线程的!
    周雪峰
    2009年8月25日 2:28
    版主
  • 你好!
         可以试试使用form.Show()方法,这个不会阻塞线程的!
    周雪峰

         可是我就是想让提示窗口独占啊,我不希望期间用户有别的操作...,并且如果用form.show()的话,鼠标动一下,提示窗口就可能跑到主窗口后面了...
    2009年8月25日 2:31
  • formParent.enable=false
    formChild.show (formParent);



    完成后 enable=true就可以了


    答案破千 马上就要到5星用户了 嘿嘿~~
    • 已建议为答案 nswdwy 2009年8月25日 3:51
    2009年8月25日 3:48
  • 几个概念一定要清晰

    1  模态窗口肯定会造成线程阻塞  除非你的任务是在后台线程处理的  

    2  独占包括两个方面 
       a 保持在parentwindow  前方  这个只需要设置他的owner   formChild.show (formParent) 就可以了
       b 在他存在的时候 不允许对后面窗体做任何操作  

    所以说 窗体的独占根本不需要模态
    答案破千 马上就要到5星用户了 嘿嘿~~
    • 已标记为答案 picat 2009年8月25日 4:04
    2009年8月25日 3:50
  •    谢谢楼上,有点懂了,不过还需要消化一下,呵呵.
    2009年8月25日 3:53
  •    正常状态下没问题了,不过在主窗口阻塞的时候,子窗口也是无响应状态,我知道这个时候应该用invoke方法吧,不过不知道该怎么调用...
       我现在是这么用的:
    Delegate Sub InvokeChildfrm()
    Private Sub frmParent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    frmChild.Invoke(New InvokeChildfrm(AddressOf Show))
    end sub
    但是运行的时候提示 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke.
    刚接触Invoke方法,不知道该怎么搞,呵呵.
    2009年8月25日 4:03
  •    正常状态下没问题了,不过在主窗口阻塞的时候,子窗口也是无响应状态,我知道这个时候应该用invoke方法吧,不过不知道该怎么调用...
       我现在是这么用的:
    Delegate Sub InvokeChildfrm()
    
    Private Sub frmParent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
    frmChild.Invoke(New InvokeChildfrm(AddressOf Show))
    
    end sub
    
    
    但是运行的时候提示 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke.
    刚接触Invoke方法,不知道该怎么搞,呵呵.

    特别说明一下,主窗口阻塞是因为,主窗口load的时候需要连接远程数据库,有时候由于网络差或者干脆不通的时候,会使主窗口失去响应直到连接完成或者报错,这也是我想做一个提示窗口的原因之一.
    2009年8月25日 4:08
  • 一般是把造成阻塞的工作放到别的线程的 
    所以整个过程都是在后台 前台没有丝毫的阻塞

    建议研究下   backgroundworker的用法


    恭喜自己5星用户达成
    2009年8月25日 4:27
  • 嗯,有道理,忘了这个了.

    2009年8月25日 4:33
  • 你好!
         第一次显示frmChild的时候才会创建句柄,当你执行frmChild.Invoke(New InvokeChildfrm(AddressOf Show))的时候,窗体还没有显示,所以句柄也没有创建,所以会出现这个错误!
         你在执行这个语句前调用窗体的CreateHandle()方法来强制创建句柄!

    周雪峰
    2009年8月25日 5:13
    版主
  •   你好周版,我没找到form的CreateHandle()方法...
    2009年8月25日 5:27
  • 不好意思,刚才的说法有问题,CreateHandle为保护方法,不能直接调用!
    那你直接访问一次Form类的Handle属性,这样也会强制创建句柄的!
    周雪峰
    2009年8月25日 5:48
    版主