С#, Windows Form, окно сообщений сверху не работает

У меня есть 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);
    }

Я бы хотел, чтобы окно сообщений было в передней части моего окна, и мне не нужно было бы менять окно, чтобы увидеть его, потому что оно находится за текущим окном.

У вас есть идея решить эту проблему?


person Alice    schedule 09.04.2013    source источник
comment
Пожалуйста, будьте более ясны, не уверен, что вы просите.   -  person Harish    schedule 09.04.2013
comment
Чего вы хотите достичь?   -  person Max    schedule 09.04.2013
comment
владелец должен быть показан в первую очередь.   -  person JSJ    schedule 09.04.2013
comment
Можете ли вы скомпилировать его, как работает TopLevel=True?   -  person Kashif    schedule 09.04.2013
comment
Я хотел бы, чтобы мое окно сообщений было перед всеми открытыми в данный момент окнами. Я использовал это окно сообщений, чтобы показать (например), что все мое представление данных сохраняется в БД или попросить пользователя указать правильный формат в текстовом поле... Пользователь должен нажать «ОК», «Да», «Нет» или «Отмена», чтобы закрыть это окно сообщения и продолжайте работать   -  person Alice    schedule 09.04.2013


Ответы (8)


Имея экземпляр вашего Form, вы можете вызвать MessageBox следующим образом:
MessageBox.show(form, "Message", "Title"); (Проверьте документ на наличие других параметров.)

Однако если вы хотите вызвать это из фонового потока (например, BackgroundWorker), вы должны использовать Form.Invoke() следующим образом:

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

Сделай это так:

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

Он поместит его перед всеми другими окнами, в том числе из других процессов (о чем, я думаю, вы просите).

Важнейшим параметром является MessageBoxOptions.DefaultDesktopOnly. Обратите внимание, что это приведет к тому, что окно сообщения будет привязано к рабочему столу по умолчанию, в результате чего приложение, вызывающее MessageBox.Show(), потеряет фокус.

(Вы действительно должны зарезервировать это поведение для критических сообщений.)

В качестве альтернативы, если ваше приложение имеет окно, вызовите this.BringToFront() перед отображением окна сообщения, вызвав MessageBox.Show() с первым параметром, установленным на this. (Вы бы назвали это из класса оконной формы).

person Matthew Watson    schedule 09.04.2013
comment
Спасибо за подсказку, но да, слишком резко - person Alice; 09.04.2013
comment
Ну, это не более радикально, чем сделать это другим способом (например, поместить окно перед всеми другими окнами в системе). В качестве альтернативы вы можете поместить само приложение на передний план. - person Matthew Watson; 09.04.2013
comment
Да, но я использую окно сообщений для многих вещей, и, к сожалению, все они важны, но я также могу потерять фокус на главном окне... Но ваше решение в некоторых случаях отличное, и я, вероятно, воспользуюсь им очень скоро! - person Alice; 09.04.2013
comment
Не могли бы вы использовать подход this.BringToFront() в основной форме? - person Matthew Watson; 09.04.2013

Я ответил на этот здесь (но, поскольку это довольно небольшой ответ, я воспроизведу его):

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

Вы устанавливаете владельца MessageBox на новую форму, которая не была показана. Вместо new Form(){TopMost=true, TopLevel=True} обратитесь к экземпляру существующей формы, над которой вы хотите поставить MessageBox.

person MrBlue    schedule 09.04.2013
comment
Я использовал свое окно сообщений в представлении окна владельца. Вы имели в виду следующее: MessageBox.Show(this.owner,.....)? - person Alice; 09.04.2013
comment
Если вы вызываете его из формы, правильным будет просто MessageBox.Show(this, .... Тем не менее, если вы вызываете его из формы, я считаю, что подразумевается владелец, поэтому вы можете полностью его исключить. - person MrBlue; 09.04.2013
comment
Не проблема увидеть владельца за мессенджером, в том-то и дело. Но здесь мне нужно сменить программу (перейти в визуальную студию или офис,...), а затем я увидел свое окно сообщений, когда вернулся к своему приложению. - person Alice; 09.04.2013
comment
Вы пробовали MessageBox.Show(this, ...? Я испытал то, что вы описываете, и явное указание владельца MessageBox всегда разрешало это для меня. - person MrBlue; 09.04.2013
comment
Да, я пытался.. Я действительно не понимаю, почему это не работает. - person Alice; 09.04.2013

В дополнение к ответу Ларса у меня была та же проблема, и метод Ларса работал, но если я затем выдавал сообщение из другого места, которое не было сверху, переключался на него, а затем сообщение снова вызывалось с использованием метода Ларса, он больше не будет на вершине.

Это вариант, который я придумал, который хорошо работает для меня, надеюсь, вы найдете его полезным:

Это запускается из отдельного потока, который имеет ссылку на основной экземпляр формы приложения.

//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");
});
person Jayd    schedule 31.01.2014

Попробуйте написать обобщающую логику как: -

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));
}
person DDave    schedule 25.03.2015

Я играл с этим и провел несколько тестов в 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");

 });
person MrJack Mcfreder    schedule 08.02.2019

просто сделайте это как обычно (MessageBox.Show(Message);) это уже самое верхнее.

см. здесь и здесь для получения информации.

person Harits Fadillah    schedule 09.04.2013