最近做一个项目(C# / winform),需要在Thread中打开一个窗口,并置最前显示,Thread在另一个单独封装的类 (TCP_ALLDV )中:
主窗口类:frm_main
线程所在类:TCP_ALLDV
要打开的窗口:frmTest
原先的代码:
主窗口frm_main:
TCP_ALLDV m_tcpDV = new TCP_ALLDV ();//定义线程类对象
m_tcpDV.Start();//启动线程
线程类(TCP_ALLDV)中的处理:
Thread m_thread_connectRequest ;//线程定义
public bool Start()//启动线程
{
m_thread_connectRequest = new Thread(Thread_TCP_connectRequest);
m_thread_connectRequest.IsBackground = true;//设置这个线程是后台线程
m_thread_connectRequest.Start();
}
private void Thread_TCP_connectRequest()
{
......
//在线程中打开一个窗口,要求保持在最前显示
frmTest testFrom = new frmTest();
testFrom .TopMost = true;
testFrom.ShowDialog();
......
}
以上代码运行结果:
1.可以打开新窗口。
2.新窗口打开时可以显示在最前。
问题:
1.用户点击主窗口,这个窗口就到后台了。
2.用户可以在主窗口上执行其它操作。
这与我的要求不相符,我希望这个线程中打开的窗口必须在最前显示,且此时用户不能操作主窗口。
原因分析:
因为线程中打开的窗口,其归属是线程,不是主窗口,所以造成以上情况。
最终解决方法:用BeginInvoke解决了问题,源码如下:
主窗口frm_main:
TCP_ALLDV m_tcpDV = new TCP_ALLDV ();//定义线程类对象
m_tcpDV.Start(this);//启动线程,注意:这里将窗口传给线程
public void OpenSeverParaSetFrm()
{
frmTest testFrom = new frmTest();
testFrom .TopMost = true;
testFrom.ShowDialog();
}
线程类(TCP_ALLDV)中的处理:
Thread m_thread_connectRequest ;//线程定义
frm_main m_mainFrm = null;//传入的主窗口
public bool Start()//启动线程
{
m_thread_connectRequest = new Thread(Thread_TCP_connectRequest);
m_thread_connectRequest.IsBackground = true;//设置这个线程是后台线程
m_thread_connectRequest.Start();
}
private void Thread_TCP_connectRequest()
{
......
MethodInvoker mi = new MethodInvoker(m_mainFrm.OpenSeverParaSetFrm);
m_mainFrm.BeginInvoke(mi);
......
}
问题解决,记录如上。
2022/7/21