我的应用程序中有一些很长的进程,所以我创建了一个WAIT PLEASE表单,然后调用另一个这样的线程:
public void ShowWait()
{
continueWait = true;
ThreadPool.QueueUserWorkItem((x) =>
{
using (frmWait espera = new frmWait())
{
espera.ShowInTaskbar = false;
espera.Show();
while (continueWait)
Application.DoEvents();
espera.Close();
}
});
}
关闭我使用的表格:
public void HideWait()
{
continueWait = false;
}
它工作正常,但我有一个问题,当显示等待表单时,主窗体失去焦点,同时运行的任何其他应用程序(Excel,Word等)到顶部,我的应用程序去在所有应用程序的后面。我尝试使用Activate()和Focus(),但只激活任务栏上的框架,但应用程序仍保留在所有应用程序的背面。
对此有何看法?
提前致谢
答案 0 :(得分:1)
您的代码段不会为我重现问题。真正重要的是主要表格正在发生什么。你看到的情况并不那么罕见。当您的等待表单关闭时,Windows会在您的应用中寻找另一个窗口以获得焦点。如果找不到,它将从另一个进程中选择另一个窗口并将其带到前台。实际上,您的主窗体将在该窗口后面消失。
当您的主窗体被禁用时,保证会发生这种情况,也许您将其Enabled属性设置为false?我想这也可能发生在你的主要表单仍然没有响应Windows消息时,那部分是黑暗的。
通过在后台线程而不是UI线程上执行耗时的代码来避免这些问题(以及用于等待表单的错误的线程单元)。 BackgroundWorker旨在简化这一过程。
答案 1 :(得分:1)
我无法复制其他应用程序,但是,与Fredrik建议放弃while循环有关,这对我有用:
AutoResetEvent processing = new AutoResetEvent(false);
private void HideWait()
{
processing.Set();
}
private void ShowWait()
{
ThreadPool.QueueUserWorkItem((x) =>
{
using (frmWait espera = new frmWait())
{
espera.ShowInTaskbar = false;
espera.Show();
processing.WaitOne();
espera.Close();
}
});
}
修改强>
避免主要形式失去焦点:
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
static readonly int SW_SHOWNOACTIVATE = 4;
AutoResetEvent processing = new AutoResetEvent(false);
private void HideWait()
{
processing.Set();
}
private void ShowWait()
{
ThreadPool.QueueUserWorkItem(c =>
{
using (frmWait espera = new frmWait())
{
espera.ShowInTaskbar = false;
ShowWindow(espera.Handle, SW_SHOWNOACTIVATE);
processing.WaitOne();
}
});
}
}
答案 2 :(得分:1)
您是否尝试使用接受所有者窗口的Show
的重载,并将空引用传递给它?我过去经历过类似的问题,这些问题已经解决了:
espera.Show(null);
调用Show()
的行为似乎有所不同(在Control
类型中实现,只是设置Visible = true
,而Form
又会触发Show(owner)
中的代码在这种情况下{1}},并调用{{1}}。
答案 3 :(得分:0)
我希望我能正确理解你的问题。所以你想将WaitForm设置在最顶层?如果是这样,你设置
espera.TopMost = true;
属性?
答案 4 :(得分:0)
我认为你想要一个模态形式,试试
espera.ShowDialog();
OTOH我真的不明白你想要什么,所以我可能错了。