C#winform:新表单可以';在任何消息框显示之前,不要处于最顶端
最近我正在编写一些代码来显示winforms应用程序未处理的异常 我希望这些异常显示窗口是最上面的 因此,我向C#winform:新表单可以';在任何消息框显示之前,不要处于最顶端,c#,winforms,exception-handling,C#,Winforms,Exception Handling,最近我正在编写一些代码来显示winforms应用程序未处理的异常 我希望这些异常显示窗口是最上面的 因此,我向Application.ThreadException添加了一个事件处理程序。处理程序创建一个新线程,打开一个新窗体,其TopMost属性设置为true 然后我意识到,即使新窗口的TopMost属性为true,它们也不可能是最顶级的更重要的是,如果显示任何MessageBox,后续的新窗口将重新获得成为顶级窗口的能力 已经有一篇帖子讨论了这个问题:但是这个答案仍然不能使我的windows
Application.ThreadException
添加了一个事件处理程序。处理程序创建一个新线程,打开一个新窗体,其TopMost
属性设置为true
然后我意识到,即使新窗口的TopMost
属性为true
,它们也不可能是最顶级的更重要的是,如果显示任何MessageBox
,后续的新窗口将重新获得成为顶级窗口的能力强>
已经有一篇帖子讨论了这个问题:但是这个答案仍然不能使我的windows成为最顶级的此外,我想知道为什么显示消息框后,最上面的是有效的。
这是我的小问题演示:
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的窗口是最高的。我只是回答问题,而不是试图说服你避免这个错误。您需要创建新表单并粘贴以下代码:
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= 8; // Turn on WS_EX_TOPMOST
return cp;
}
}
现在,即使从另一个线程显示,它也将位于最顶端。乍一看似乎是线程问题。。我绝对建议您在代码中添加一些断点,然后使用调试器单步执行代码。。我怀疑您的问题在这行
Thread t=new Thread(new ThreadStart(()=>{
而且您在if(MessageBox.Show
为什么不将代码包装在代码块中?@MethodManif(MessageBox.Show
只显示一个MessageBox,if块为空,只有一个;
…我不知道创建线程的问题在哪里?。您不应该在主UI线程之外的任何其他线程中创建任何窗口。但也就是说,我无法使用您显示的代码重现您描述的问题。运行co反独立(即,不是从调试器,当抛出异常时,调试器会窃取焦点),单击按钮后,我看到三个最上面的窗口和消息框。最上面的窗口甚至保留在消息框的上方,以及我桌面上的其他窗口。您是否在调试器之外尝试了他的示例代码?当我运行OP的代码时,它会按照预期工作:所有显示的窗口都是“最上面的”(很明显,只有一个最顶级的窗口可以真正成为最顶级的窗口……但它们都在其他所有窗口之上,包括来自其他进程的窗口)。是的,我在发布之前测试了这段代码。OP也测试了它,发现它解决了他的问题。我期待它。不,我不是指你的代码。我是指OP的代码。“他的示例代码”。我无法重现他描述的问题。你能吗?(不管怎样,我认为你至少应该试着说服他放弃他糟糕的设计……但我更好奇的是,你一开始是否能够证实他的投诉).在过去的好日子里,用户分享了他们的知识,提问者和回答者一样参与其中。那些日子已经过去了,OP只是不想分享他知道的、我们不知道的、会使代码变得有用的东西。在这个非常不明显的技术答案上,惊人的投票数给了我一个不可能的机会我不知道你为什么希望我这么做。如果你想了解更多,就点击提问按钮。我相信这将是一个比这个更好的问题。“不知道你为什么希望我这么做”——我不会说“希望”“是正确的词。就我个人而言,如果我自己无法重现所描述的问题,我几乎从不费心回答问题;很容易意外地提供一个无用的答案(即,要么解决了不存在的问题,要么未能解决原始问题).但我不希望你或其他任何人一定会认同这种哲学。我只是好奇你是否能够重现这个问题。不管怎样,都没有期望。