【问题标题】:C#, Windows Form, Messagebox on top not workingC#、Windows 窗体、顶部的消息框不起作用
【发布时间】:2013-04-09 11:49:53
【问题描述】:

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

MessageBox.Show(new Form(){TopMost=true, TopLevel=True}, "Message","Title", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

举个更好的例子,我为 FormClosing 事件这样做:

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 或只尝试了 TopLevel,StartPosition=FormStartPosition.CenterScreen 但没有任何效果。

[更新]

我试过了:

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

我想将我的 messageBox 放在窗口的前面,而不必更改窗口即可看到它,因为它就像在当前窗口的后面。

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

【问题讨论】:

  • 请说的更清楚些,不知道你在问什么。
  • 你想达到什么目的?
  • 需要先显示所有者。
  • 能不能编译一下,TopLevel=True 是怎么工作的?
  • 我想让我的消息框出现在所有其他当前打开的窗口的前面。我使用这些消息框来显示(例如)我所有的 datagridview 都保存在 db 上,或者要求用户在文本框中输入一些正确的格式,... 用户必须单击 Ok、Yes、No 或取消才能关闭这个消息框,继续工作

标签: c# messagebox topmost


【解决方案1】:

这样做:

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

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

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

(你真的应该为关键消息保留这种行为。)

或者,如果您的应用程序有一个窗口,则在显示消息框之前调用 this.BringToFront(),方法是调用 MessageBox.Show(),并将第一个参数设置为 this。 (你可以从窗体类中调用它)。

【讨论】:

  • 谢谢你的提示,但是是的,有点太激烈了
  • 嗯,这并不比以其他方式(即将窗口放在系统上所有其他窗口的前面)更激烈。或者,您可能希望将应用程序本身置于前台。
  • 是的,但我在很多事情上都使用消息框,不幸的是,所有事情都很重要,但我也会失去对主窗口的关注......但在某些情况下你的解决方案很棒,我可能很快就会使用它!
  • 可以在主窗体上使用this.BringToFront() 方法吗?
【解决方案2】:

给定您的Form 实例,您可以像这样调用MessageBox
MessageBox.show(form, "Message", "Title"); (Check the doc for other parameters.)

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

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

【讨论】:

    【解决方案3】:

    我已经回答了这个here(但因为它是一个相当小的答案,我会复制它):

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

    【讨论】:

      【解决方案4】:

      您正在将 MessageBox 所有者设置为尚未显示的新表单。而不是new Form(){TopMost=true, TopLevel=True},请引用您希望在其顶部添加MessageBox 的现有表单的实例。

      【讨论】:

      • 我在所有者窗口的视图中使用了我的消息框。你的意思是这样的:MessageBox.Show(this.owner,.....)?
      • 如果您从表单中调用它,只需 MessageBox.Show(this, ... 即可。也就是说,如果您从表单中调用它,我相信所有者是隐含的,因此您可以完全忽略它。
      • 看到消息框后面的所有者不是问题,这就是重点。但是在这里,我必须更改程序(去 Visual Studio 或办公室,......)然后当我回到我的应用程序时我看到了我的消息框
      • 你试过MessageBox.Show(this, ...吗?我已经经历过您所描述的内容,并且明确设置MessageBox 的所有者始终为我解决了这个问题。
      • 是的,我试过了。我真的不明白为什么它不起作用。
      【解决方案5】:

      在 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");
      });
      

      【讨论】:

        【解决方案6】:

        尝试将泛化逻辑写成:-

        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));
        }
        

        【讨论】:

          【解决方案7】:

          我一直在玩这个并在 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");
          
           });
          

          【讨论】:

            【解决方案8】:

            照常做 (MessageBox.Show(Message);) 它已经是最上面的了。

            有关信息,请参阅 herehere

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-10-19
              • 1970-01-01
              • 1970-01-01
              • 2017-11-10
              相关资源
              最近更新 更多