最近我写了一些代码来显示winforms app的未处理异常。
我希望那些例外显示窗口是TopMost。
所以我向Application.ThreadException
添加了一个事件处理程序。处理程序创建一个新线程,打开一个TopMost
属性设置为true
的新表单。
然后我意识到,即使他们的TopMost
属性为true
,新窗口也无法成为TopMost。 更重要的是,如果显示任何MessageBox
,后续的新窗口将重新获得成为TopMost的能力!
已经有一篇文章讨论了这个问题:TopMost form in a thread?但是这些答案仍然不能让我的Windows TopMost。 此外,我想知道显示TopMost
后MessageBox
有效的原因。
这是我的最小问题演示:
using System;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += (o, e) => handleException();
Application.Run(new Form1());
}
static void handleException()
{
// before messagebox
doDisplay(); //Count:1
doDisplay(); //Count:2
doDisplay(); //Count:3
// Delay a while for the display threads to run
Thread.Sleep(300);
// show messagebox
if (MessageBox.Show("It doesn't matter you choose YES or NO",
"Message", MessageBoxButtons.YesNo) == DialogResult.No)
; // empty statement, just show msgbox
// after messagebox
doDisplay(); //Count:4
doDisplay(); //Count:5
doDisplay(); //Count:6
}
static int count = 0;
static void doDisplay()
{
Thread t = new Thread(new ThreadStart(() =>
{
Form f = new Form();
f.TopMost = true;
f.Text = "Count: " + ++count;
f.ShowDialog();
}));
t.IsBackground = true;
t.Start();
}
}
public class Form1 : Form
{
public Form1()
{
Button b = new Button();
b.Text = "throw!";
b.Click += (o, e) => { throw new Exception(); };
this.Controls.Add(b);
}
}
}
输出:具有计数的窗口:1/2/3 不是最顶部,具有计数的窗口:4/5/6 最顶层。
答案 0 :(得分:0)
我只是回答这个问题而不是试图告诉你这个错误。您需要创建一个新表单并粘贴此代码:
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= 8; // Turn on WS_EX_TOPMOST
return cp;
}
}
现在即使从另一个线程显示它也将是最顶层的。