c#, Windows窗体,Messagebox在顶部不工作

本文关键字:顶部 工作 Messagebox Windows 窗体 | 更新日期: 2023-09-27 18:08:27

我有一些MessageBox,我像这样编码:

MessageBox.Show(new Form(){TopMost=true, TopLevel=True}, "Message","Title", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
对于一个更好的例子,我这样做FormClosing Event:
private void Example_FormClosing(object sender, FormClosingEventArgs e){
MessageBox.Show(new Form(){TopMost=true, TopLevel=True}, "Really close?"," Program", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
}

但是,几乎每次我必须在我的电脑上更换窗口(比如返回Visual Studio)才能看到我的消息框,它不是用户友好的,真的很烦人。

我验证了我的主要形式不是在TopMost=true,我尝试只是TopMost或只是topplevel, StartPosition=FormStartPosition。

(更新)

我试着:

 private void Example_FormClosing(object sender, FormClosingEventArgs e){
    MessageBox.Show(this.Owner, "Really close?"," Program", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
    }

我想让我的messageBox在我的窗口前面,而不必改变窗口来看到它,因为它就像在当前窗口后面。

你有解决这个问题的办法吗?

c#, Windows窗体,Messagebox在顶部不工作

这样做:

MessageBox.Show(
    "Message", 
    "Title", 
    MessageBoxButtons.YesNo, 
    MessageBoxIcon.Warning, 
    MessageBoxDefaultButton.Button1, 
    MessageBoxOptions.DefaultDesktopOnly);

它将把它放在所有其他窗口的前面,包括来自其他进程的窗口(我认为这是您要求的)。

关键参数为MessageBoxOptions.DefaultDesktopOnly。注意,这将使消息框父化到默认桌面,导致调用MessageBox.Show()的应用程序失去焦点。

(您应该为重要消息保留此行为)

或者,如果你的应用程序有一个窗口,在显示消息框之前通过调用MessageBox.Show()调用this.BringToFront(),第一个参数设置为this

给定一个Form的实例,你可以这样调用MessageBox:
MessageBox.show(form, "Message", "Title");(其他参数请参考文档)

然而如果你想从后台线程(例如:BackgroundWorker)调用它,你必须像这样使用Form.Invoke():

form.Invoke((MethodInvoker)delegate
{
   MessageBox.show(form, "Message", "Title");
});

我已经在这里回答了这个问题(但由于这个答案相当小,我将重复它):

using (var dummy = new Form() { TopMost = true })
{
    MessageBox.Show(dummy, text, title);
}

您正在将MessageBox所有者设置为尚未显示的新表单。代替new Form(){TopMost=true, TopLevel=True},引用一个您希望MessageBox放在上面的现有表单的实例。

对于Lars的回答,我也遇到了同样的问题,Lars的方法是有效的,但是如果我从其他地方弹出一条不在顶部的消息,切换到它,然后使用Lars的方法再次调用该消息,它将不再位于顶部。

这是我想出的对我来说很有效的变化,希望你能发现它有帮助:

这是在一个单独的线程中运行的,它引用了主应用程序表单实例

//Show message on top of all other forms
MainFormInstance.Invoke((MethodInvoker)delegate
{
    Form popup = new Form() { TopMost = true, TopLevel = true };
    MessageBox.Show(popup, "Message", "Title");
});

尝试将泛化逻辑写为:-

public static DialogResult ShowMessage(Form Parent, string Text, string Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon, MessageBoxDefaultButton DefaultButton)
{
    if (Parent != null && Parent.InvokeRequired)
        return (DialogResult) Parent.Invoke(((Func<DialogResult>))(() => MessageBox.Show(Text, Caption, Buttons, Icon, DefaultButton)));
    else
        return (MessageBox.Show(Text, Caption, Buttons, Icon, DefaultButton));
}

我一直在玩这个,并在Windows 7/8.1/10上运行了多次测试,然后终于找到了一个在上面提到的所有系统中显示消息框的工作方法。

//Create an Empty Form with TopMost & TopLevel attributes.
Form popup = new Form() { TopMost = true, TopLevel = true };
//Running MessageBox on a different Thread
              Invoke((MethodInvoker)delegate {
     DialogResult dialogResult = MessageBox.Show(popup, "Custom Message Here", MessageBoxButtons.YesNo);
              if (dialogResult == DialogResult.Yes)
              {
                  //do something
              }
              else if (dialogResult == DialogResult.No)
              {
                  //do something else
              }
//Or a casual message box
//MessageBox.Show(popup, "Custom Message Here", "Alert");
 });

就像往常一样(MessageBox.Show(Message);),它已经在最上面了。