Pass in der übergeordneten form von ShowDialog, die aufgerufen wird, eine Instanz der Klasse
Ich habe ein Formular.
In dieser form erstelle ich eine Instanz einer Klasse in einem neuen thread, weil es läuft einige lang laufende Logik. Die form gibt dem Benutzer die Möglichkeit zum Abbrechen dieser Logik/thread.
Diese Klasse öffnet ein neues Formular aus, wenn eine Eingabe erforderlich.
Die neue form manchmal erscheint hinter der anderen form.
Ich eine Eigenschaft der Klasse:
public Form ParentForm{get;set;}
Kann ich jetzt tun:
MyForm form = new MyForm();
form.ShowDialog(ParentForm);
Jedoch bekomme ich eine cross-thread-exception beim Aufruf ShowDialog(ParentForm)
.
Ich weiß, dass ich verwenden können InvokeRequired
irgendwie aber nicht sicher, wie Sie Sie auf eine Eigenschaft.
Dank
UPDATE: Habe versucht dies zu tun aber bekomme immer noch die Ausnahme:
MyForm form = new MyForm();
form.ShowDialog(GetParentForm());
private Form GetParentForm()
{
//You have to Invoke() so you can wait for the function to return and obtain its return value.
if (ParentForm.InvokeRequired)
{
return (Form)ParentForm.Invoke(new Func<Form>(() => GetParentForm()));
}
else
{
return ParentForm;
}
}
- Winforms flubs diese Prüfung und umgangen werden kann, aber das problem ist bezeichnend für ein größeres Problem. Sie schob sich ein dialog, wenn der Benutzer arbeitet mit einem Fenster auf Ihrem Haupt-thread. Wenn Sie nicht erwarten, dass es. Chancen sind hoch, dass Sie versehentlich schließen Sie das Dialogfenster mit einem Mausklick oder Tastendruck, die bestimmt war für das Hauptfenster. Sie werden noch nicht einmal sehen, den dialog. Das problem beheben Sie zuerst, und Sie werden nicht über dieses problem.
- Ist der Nutzer es erwartet. Sie auf eine Schaltfläche klicken, beginnt der Faden, und Sie haben einen laden von gif zu zeigen, die Aufgabe ist ausgeführt und wissen, zu warten, bis Sie zurückkehren oder die Interaktion mit popup, die angezeigt werden können
- Gut, dann eben auf dem UI-thread. Verwenden Sie Die Kontrolle.BeginInvoke()
- Wie rufe ich die showMyNewForm aus meiner eigenen Klasse in einem anderen thread und testen Sie seine ModalResult?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre aktualisierte Methode (
GetParentForm
) wird nicht arbeiten, weil Sie das einwickeln der Aufgabe des Erhaltens der Verweis aufParentForm
in einemInvokeRequired
block. Sie könnten versuchen, das einwickeln derShowDialog
rufen Sie in einen solchen block statt, aber ich denke, man würde immer noch den cross-threading Fehler.Ihre einfachste fix wäre, um den code, der erstellt und zeigt die zweite form aus Ihrer Klasse und in
ParentForm
. Anstatt also diese:tun Sie dies:
und in
ParentForm
Sie hätte diese:Wenn
MyForm
muss eine Referenz auf die Klasse, auf den anderen thread, fügen Sie einfach ein parametershowMyNewForm()
so, dass der Verweis auf Sie kann übergeben werden.Was Sie hier versuchen (erstellen und zeigen im Zusammenhang, verbunden mit Formen, die erstellt werden, in verschiedenen threads) ist wirklich gegen den Strich, wie die Formen sind nicht vorgesehen .NET.
showMyNewForm()
so, dass es gibt, was Informationen, die Sie sammeln aus der dialog (stellen Sie den return-Typstring
oder was auch immer Sie brauchen), und rufen Sie dann showMyNewForm(), mit der gleichen Art von syntax, wie in Ihrem Beispiel-Methode. Konzeptionell du bist, dann lassen ParentForm den job zu behandeln das sammeln dieser Informationen von dem Benutzer, und Sie Ihre lange-task-thread nicht (und sollte nicht) wissen nichts darüber, wie dies geschehen ist.können Sie hinzufügen async-Methode, um ein Formular.
Sagen wir mal so:
und verwenden Sie diese, wie:
Sollte für Sie arbeiten.
Übrigens, wenn Ihr problem ist nur die Tatsache, dass das Fenster erscheint auf bihind der andere, versuchen zu nutzen Form.Oberste Eigenschaft Einstellung
true
. In dem Bewusstsein, dass es, ja, bringen Sie es vor anderen Formen, aber nicht nötig vor anderen obersten Formen.