现在要做一个登录的功能,操作的步骤如下:
1、启动程序,显示登录界面。
2、用户填写相关信息,点击“登录”。
3、启动新线程(登录线程)来处理登录事务,界面上有progressbar在不断变动。
4、登录线程处理完毕登录事务。
5、隐藏登录窗口,打开新窗口,进入另一界面。以上需求我想是很普通的。
现在的问题是:
我在哪里来实现“隐藏登录窗口,打开新窗口”。
如果在线程中来实现,那么新开窗口永远都是属于登录线程的。也就是说之后的程序都在登录线程中运行。
如果在UI线程中来实现,那么UI线程如何知道登录线程已处理完毕。已经尝试过在登录线程中触发自定义事件来开新窗口,但结果是一样的,还是属于”跨线程调用控件“。请各位给出答案。100分。
1、启动程序,显示登录界面。
2、用户填写相关信息,点击“登录”。
3、启动新线程(登录线程)来处理登录事务,界面上有progressbar在不断变动。
4、登录线程处理完毕登录事务。
5、隐藏登录窗口,打开新窗口,进入另一界面。以上需求我想是很普通的。
现在的问题是:
我在哪里来实现“隐藏登录窗口,打开新窗口”。
如果在线程中来实现,那么新开窗口永远都是属于登录线程的。也就是说之后的程序都在登录线程中运行。
如果在UI线程中来实现,那么UI线程如何知道登录线程已处理完毕。已经尝试过在登录线程中触发自定义事件来开新窗口,但结果是一样的,还是属于”跨线程调用控件“。请各位给出答案。100分。
或者form的invoke?
使用Application.Run (ApplicationContext) 方法
在特定的 ApplicationContext 中,在当前线程上开始运行标准应用程序消息循环。参考
http://msdn2.microsoft.com/zh-CN/library/ms157901.aspx
this.Visible = false;
然后,打开新窗口
/// 登录按钮响应事件。
/// </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;
}
}
http://blog.csdn.net/knight94/archive/2006/05/27/757351.aspx
用你说的办法做完以后,以callback里操作登录窗体时,又告诉我在跨线程操作控件了。
{
//通过委托实现回调
ShowMessageBoxDelegate smbd = new ShowMessageBoxDelegate(ShowMessageBox);//回调
Invoke(smbd, list);//第2个参数才是回调函数的形参
}void ShowMessageBox(参数 list)
{
// list做其他的事情
NewForm form=new NewForn();
form.show();//展现新窗体
}
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();
同时写一个对应的方法 private void Hidden(......)
具体参数想不起来了,但最后一个应该是 EventArg
具体方法可以联系我
MSN [email protected]
好象也是处于与UI线程不同的线程中,对登录窗口的hide()也被提示为跨线程访问控件。
______________________________你不知道所有的UI控件有个Invoke方法么?Control的Invoke方法即是使此方法在控件所在的线程执行。Form也是继承自Control。
你说的方法我试过,在登录线程中this.invoke来启动开新窗口,关本窗口的方法,
但是新窗口打开后,点击右上角的 X 把它关掉,但程序还没有结束运行,
说明还有一个线程在运行。哪位能给出代码,再加100分。
你在最后关闭那个窗口的FormClosing事件里面写
Application.Exit();
www_123du_com(鼠·神·泪)
你说的方法我试过,在登录线程中this.invoke来启动开新窗口,关本窗口的方法,
但是新窗口打开后,点击右上角的 X 把它关掉,但程序还没有结束运行,
说明还有一个线程在运行。哪位能给出代码,再加100分。
______________________________不知你用Invoke调用的方法是怎么写的,大概可以如下:
this.Hide(); //隐藏登陆窗口
mainForm.ShowDialog(); //打开主窗口
this.Close(); //关闭登陆窗口,由于登陆窗口是主窗口,所以程序结束(没有IsBackground为false的线程的话)
源代码联系[email protected]
先启动新窗口,然后隐藏他,然后起登录验证窗口,如果登录成功则关闭登陆窗口再显示新窗口,否则直接关闭新窗口。
方法2:
在新窗口的closed事件中加
Application.Exit();
即可
只是我没发现有一个窗口被hide了,所有关闭所有窗口时程序没有结程。谢谢各位。结贴,放分。