现在要做一个登录的功能,操作的步骤如下:
1、启动程序,显示登录界面。
2、用户填写相关信息,点击“登录”。
3、启动新线程(登录线程)来处理登录事务,界面上有progressbar在不断变动。
4、登录线程处理完毕登录事务。
5、隐藏登录窗口,打开新窗口,进入另一界面。以上需求我想是很普通的。
现在的问题是:
我在哪里来实现“隐藏登录窗口,打开新窗口”。
  如果在线程中来实现,那么新开窗口永远都是属于登录线程的。也就是说之后的程序都在登录线程中运行。
  如果在UI线程中来实现,那么UI线程如何知道登录线程已处理完毕。已经尝试过在登录线程中触发自定义事件来开新窗口,但结果是一样的,还是属于”跨线程调用控件“。请各位给出答案。100分。

解决方案 »

  1.   

    用回调?
    或者form的invoke?
      

  2.   

    启动登录线程这一步用异步调用,BeginInvoke有一个callback参数,它是一个委托变量,你在这个委托里面隐藏登录窗口,打开新窗口
      

  3.   

    可以
    使用Application.Run (ApplicationContext) 方法  
    在特定的 ApplicationContext 中,在当前线程上开始运行标准应用程序消息循环。参考
    http://msdn2.microsoft.com/zh-CN/library/ms157901.aspx
      

  4.   

    在点击“登录",如果登录成功,
            this.Visible = false;
    然后,打开新窗口
      

  5.   

    /// <summary>
            /// 登录按钮响应事件。
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void buttonLogin_Click(object sender, System.EventArgs e)
            {
                // 建一个timer来定时刷新进度条
                // 设定3秒,每隔0.3秒刷新一次
                System.Threading.Timer timer = null;
                
                try
                {
                    this.progressBar.Visible = true;
                    this.progressBar.Value = this.progressBar.Minimum;
                    
                    TimerCallback timerDelegate = new TimerCallback(RefreshProgressBar);
                    timer = new System.Threading.Timer(timerDelegate, this, 0, 300);                string empNo = this.textBoxUserName.Text.Trim();
                    string psw = this.textBoxPassword.Text; //密码可以包含空格                UserLoginReturnInfo returnInfo = UserServiceProxy.Login(empNo, psw); 
                    
                    // 设置客户端全局缓存信息
                    ClientGlobalInfo.RequestCommonInfo = new RequestCommonInfo(empNo, returnInfo.Ticket);
                    ClientGlobalInfo.RawCommonData = returnInfo.CommonData;
                    ClientGlobalInfo.UserInfoEntity = returnInfo.UserInfo;               
                    
                    this._Menu = returnInfo.Menu;
                    this.ServerDate = returnInfo.ServerDate;                this.SaveLastLoginUserName(empNo);
                    this._IsLoginOk = true;      
              
                    this.progressBar.Value = this.progressBar.Maximum;
                    timer.Dispose();
                    
                    this.Close();
                }
                catch(Exception ex)
                {
                    timer.Dispose();
                    if (ex is UserNoExistException || ex is InvalidPasswordException)
                    {
                        this.ShowMessage("用户名或密码错误,请重新输入。");
                    }
                    else
                    {
                        if (ex is UserDisabledException)
                        {
                            this.ShowMessage(ex.Message);
                        }
                        else
                        {
                            ExceptionHandler.HandleException(ex);
                        }
                    }
                }
                finally
                {
                    this.progressBar.Visible = false;                
                }
            }
      

  6.   

    ref:
    http://blog.csdn.net/knight94/archive/2006/05/27/757351.aspx
      

  7.   

    1. 你的整个流程都不需要异步线程。如果打算异步,你要回答清楚异步的时候登录窗口做什么的问题。如果这个不知道,阻塞在那里什么也不做,那么这个线程纯粹是为了线程而线程地空想。2. 你的Prpgressbar是在哪里?在登录窗口上比较简单,只不过此窗口会根据状态不同(时候正在登录)有不同的表现。使用另外一个专门显示进度条的窗体并且使用ShowDialog()来调用它也不难,而且也不需要线程控制。不过仅仅是一个信令交互过程,用进度条似乎不对,充其量显示一个动画就行了。3. 登录之后,应该实例化下一个窗口,并且挂接处理它的Closed事件(通知自己也自动Close),然后把自己窗口隐藏即可。
      

  8.   

    v192(人都是環境逼出來的,所以往死裏逼我吧)  
    用你说的办法做完以后,以callback里操作登录窗体时,又告诉我在跨线程操作控件了。
      

  9.   

    而且在callback里打开的新窗口好象死了一样,无法操作,窗体标题还是xxx(没有响应)
      

  10.   

    我这几天做了和你说的差不多的功能可以用回调来完成void 线程函数()
    {
    //通过委托实现回调
    ShowMessageBoxDelegate smbd = new ShowMessageBoxDelegate(ShowMessageBox);//回调
    Invoke(smbd, list);//第2个参数才是回调函数的形参
    }void ShowMessageBox(参数 list)
    {
       // list做其他的事情
       NewForm form=new NewForn();
       form.show();//展现新窗体
    }
      

  11.   

    很简单的:
    1、在UI线程开启登录窗口
    2、点击登录开启登录线程
     System.Threading.Thread t = new System.Threading.Thread(new 
                                     System.Threading.ThreadStart(Login));
     t.Start();在定义一个LoginOver方法,该方法支持异步线程的调用
    public void LoginOver()
    {
        if (InvokeRequired)
        {
            BeginInvoke(new LoginOverDelegate(LoginOver)); //注意这里的写法LoginOver
                                
            return;
        }
        隐藏登录窗口
        打开新的窗口
    }
    定义一个登录完成的委托的委托
    private  delegate void LoginOverDelegate();
      

  12.   

    在你线程调用的那个方法结尾加上某个窗体控件的 BeginInvoke(new Hidden(......)) 方法
    同时写一个对应的方法 private void Hidden(......)
    具体参数想不起来了,但最后一个应该是 EventArg
      

  13.   

    在新起的线程里是不能对FORM里的控件进行操作的
    具体方法可以联系我 
    MSN [email protected]
      

  14.   

    可以使用callback函数来实现异步操作的。
      

  15.   

    同样,如果使用异步调用,其结果也是一样的,在异步调用完成时触发的回调方法时,
    好象也是处于与UI线程不同的线程中,对登录窗口的hide()也被提示为跨线程访问控件。
      

  16.   

    主页里链接进来,说实话C#也不懂多少,如果是在VC里面,我肯定会在那个线程结束之前PostMessage到主线程,然后就OK了。不知道C#行不行。
      

  17.   

    如果在UI线程中来实现,那么UI线程如何知道登录线程已处理完毕。
    ______________________________你不知道所有的UI控件有个Invoke方法么?Control的Invoke方法即是使此方法在控件所在的线程执行。Form也是继承自Control。
      

  18.   

    www_123du_com(鼠·神·泪) 
    你说的方法我试过,在登录线程中this.invoke来启动开新窗口,关本窗口的方法,
    但是新窗口打开后,点击右上角的 X 把它关掉,但程序还没有结束运行,
    说明还有一个线程在运行。哪位能给出代码,再加100分。
      

  19.   

    楼上:
    你在最后关闭那个窗口的FormClosing事件里面写
    Application.Exit();
      

  20.   

    VFanYan() ( ) 信誉:67    Blog  2006-08-31 14:46:00  得分: 0  
     
     
    www_123du_com(鼠·神·泪) 
    你说的方法我试过,在登录线程中this.invoke来启动开新窗口,关本窗口的方法,
    但是新窗口打开后,点击右上角的 X 把它关掉,但程序还没有结束运行,
    说明还有一个线程在运行。哪位能给出代码,再加100分。
    ______________________________不知你用Invoke调用的方法是怎么写的,大概可以如下:
    this.Hide();   //隐藏登陆窗口
    mainForm.ShowDialog();   //打开主窗口
    this.Close();   //关闭登陆窗口,由于登陆窗口是主窗口,所以程序结束(没有IsBackground为false的线程的话)
      

  21.   

    线程和事件就可以实现,
    源代码联系[email protected]
      

  22.   

    方法1:
       先启动新窗口,然后隐藏他,然后起登录验证窗口,如果登录成功则关闭登陆窗口再显示新窗口,否则直接关闭新窗口。
    方法2:
      在新窗口的closed事件中加 
          Application.Exit();
    即可
      

  23.   

    对不起,各位,其实这个问题我弄错了,早在发贴前已经解决了。
    只是我没发现有一个窗口被hide了,所有关闭所有窗口时程序没有结程。谢谢各位。结贴,放分。