Warum ist ein C # /. NET-Meldungsfeld nicht modal?
Wenn sich das Meldungsfeld versehentlich hinter unserer Hauptbenutzeroberfläche befindet, reagiert die Hauptbenutzeroberfläche nicht, bis wir auf OK klicken (im Meldungsfeld).
Gibt es eine andere Problemumgehung als das Erstellen eines benutzerdefinierten Meldungsfelds?
Sie müssen die MessageBox-Besitzereigenschaft dem Hauptfenster der Benutzeroberfläche zuweisen (siehe 3. Konstruktor).
Dies ist eine einfache, neue C # -Anwendung von Windows Forms:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string message = "You did not enter a server name. Cancel this operation?";
string caption = "No Server Name Specified";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
DialogResult result;
// Displays the MessageBox.
result = MessageBox.Show(this, message, caption, buttons);
if (result == DialogResult.Yes)
{
// Closes the parent form.
this.Close();
}
}
}
}
Wie Dusty in seiner Antwort angibt, ist ein Meldungsfeld ein modaler Dialog. Geben Sie die Eigenschaft 'owner' an. In diesem Beispiel wird der Besitzer mit dem Schlüsselwort 'this' bezeichnet.
Um systemmodale Messagebox zu erhalten, setzen Sie MessageBoxOptions.DefaultDesktopOnly .
Ein modales Popup wird technisch als ein Popup-Fenster definiert, das den normalen Fluss der Anwendung unterbricht. Nicht unbedingt eines, das oben auf allen anderen Fenstern angezeigt wird. Daher ist das von Ihnen beschriebene Verhalten für ein modales Popup richtig .
Hier ist ein Projekt in CodeProject, das versucht, die Funktionalität "Immer im Vordergrund" für ein MessageBox-Stil-Modal-Fenster nachzuahmen:
Mit dem Parameter owner können Sie ein bestimmtes Objekt angeben, das die Schnittstelle IWin32Window implementiert, um das Meldungsfeld vor zu platzieren.
Ein Meldungsfeld ist ein modales Dialogfeld, dh es kann keine Eingabe (Tastatur oder Mausklick) erfolgen, außer an Objekten im modalen Formular. Das Programm muss ein modales Formular ausblenden oder schließen (normalerweise als Reaktion auf eine Benutzeraktion), bevor Eingaben in ein anderes Formular erfolgen können.
Was ich normalerweise mache, wenn ich eine MessageBox aus einem anderen Thread (nicht aus dem Haupt-Thread) auslösen muss, ist dies:
Ich erstelle eine statische Variable mit der Formularinstanz:
private statische Form1 myform;
Vom Thread aus rufe ich die Operation auf, um die MessageBox vom Hauptthread aus anzuzeigen:
myform.BeginInvoke ((MethodInvoker) delegate () {MessageBox.Show ("Prozess beendet!", "Thread-Prozessinformationen", MessageBoxButtons.OK, MessageBoxIcon.Information);});
Dies ist nur ein "Ausstecher", den ich immer benutze und funktioniert perfekt für mich.
Lassen Sie das Meldungsfeld im Hauptthread erscheinen, wenn Ihr Formular daraus erstellt wurde:
private bool ShowMessageBoxYesNo()
{
if (this.InvokeRequired)
return (bool)this.Invoke(new ShowMessageBoxYesNoDelegate(ShowMessageBoxYesNo));
else
{
DialogResult res = MessageBox.Show("What ?", "Title", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (res == DialogResult.Yes)
return true;
else
return false;
}
}
Das funktioniert für mich:
MessageBox.Show(Form.ActiveForm,"Finished processing", "Process finished", , MessageBoxButtons.OK, MessageBoxIcon.Information);
Form.ActiveForm würde Ihnen das aktuell aktive Formular geben, selbst wenn Sie Ihre MessageBox von einer anderen Klasse verwenden.