Form in anderem Thread erstellen, wie es angezeigt wird

Julian-w

Mitglied
Hallo,
wie der Titel schon sagt, ich erstelle ein WinForm in einem anderen Thread (BackgroundWorker) und zeige es in einem anderen Thread an. Hier mal das Code-Bsp:

Code:
// Fenster
private Forms.Main _window;

//BackgroundWorker
private void BW_System_starten_DoWork(object sender, DoWorkEventArgs e)
{
    Main Fenster = new Main();
    BW_System_starten.ReportProgress(20, Fenster);
}

private void BW_System_starten_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    statusItem6.Value = e.ProgressPercentage;

    if (e.UserState != null)
    {
        this._window = (Main)e.UserState;
    }
}

private void Fenster_anzeigen()
{
    System.Threading.ThreadStart c = new System.Threading.ThreadStart(Fenster_anezigen_Multithread);
    System.Threading.Thread Thread = new System.Threading.Thread(c);
    Thread.Start();
}

private void Fenster_anezigen_Multithread()
{
    Application.Run(this._window);
}

Hoffe, ihr könnt mir helfen
 
Hallo,

ich kann aus deinem Beitrag nicht erkennen, was genau dein Problem dabei ist.

Falls du meinst, wie du auf ein Form zugreifen kannst, welches in einem anderen Thread ist, als der, von dem aus du darauf zugreifen willst, dann musst du ein Invoke auf das Form ausführen. (dies geht aber erst, wenn das Fenster-Handle erstellt wurde, also denke ich, du kannst ein Application.Run() auf ein in einem anderen Thread erzeugtes Form ausführen).
Also nachdem der Thread beendet wurde, kann man dann z.B. die Position des Fensters so setzen:
Code:
MethodInvoker SetPosition = delegate
{
    this._window.Location = new Point(20, 20);
};
this._window.Invoke(SetPosition);

Aber beschreibe mal dein Problem, denn so kann denke ich keiner helfen, da niemand dein Problem kennt ;)

MfG
Fabsch
 
OK, dann drück ich mich etwas deutlicher aus:

Im BackgroundWorker wird das Fenster erstellt
Code:
private void BW_System_starten_DoWork(object sender, DoWorkEventArgs e)
{
    Main Fenster = new Main();
    BW_System_starten.ReportProgress(20, Fenster);
}
und dann in einer Variablen in der Klasse gespeichert:
Code:
private Forms.Main _window;
private void BW_System_starten_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    statusItem6.Value = e.ProgressPercentage;

    if (e.UserState != null)
    {
        this._window = (Main)e.UserState;
    }
}

Wenn der BackgroundWorker nun fertig ist,laufen noch ein paar andere Prozesse ab (die hier nicht von Bedeutung sind). Am Ende aber wird auf das Form wieder zurückgegriffen, dass nun in einem anderen Thread gestartet werden soll:
Code:
private void Fenster_anzeigen()
{
    System.Threading.ThreadStart c = new System.Threading.ThreadStart(Fenster_anezigen_Multithread);
    System.Threading.Thread Thread = new System.Threading.Thread(c);
    Thread.Start();
}

private void Fenster_anezigen_Multithread()
{
    // FEHLER
    Application.Run(this._window);
}

Und hier tritt der Fehler auf, denn das Fenster wird nicht gestartet.

Zusammenfassung:
Hauptthread
-> erstellt BackgroundWorker Thread, in dem das Fenster erzeugt wird. Danach wird der Thread beendet.
-> GUI-Thread: Hier soll das Fenster mithilfe von Application.Run() angezeigt werde.

Hoffe, ihr versteht jetzt, was mein Problem ist. Das Fenster wird in Thread A erstellt und soll in Thread B angezeigt werden.
 
Hmm, soweit ich weiß, ist das nicht möglich.
Aber wieso öffnest du das Form nicht im gleichen Thread, wie dort die Klasse?
Der Background-Worker macht ja alles, was er macht in einem Thread, also wird das Form nicht blockiert, wenn du das Form im gleichen Thread wie die Klasse in dem der Background-Worker erzeugt und gestartet wird, anzeigst.

Aber ansonsten.. probier mal im Konstruktor des Forms das Fensterhandle mit
Code:
this.CreateHandle();
zu erzeugen, dann kannst du denke ich in das Form Invoken und so dann das Form anzeigen:
Code:
private void Fenster_anezigen_Multithread()
{
    MethodInvoker RunApp = delegate
    {
        Application.Run(this._window);
    };
    this._window.Invoke(RunApp);
}

Aber ansonsten gibt es da keine Möglichkeit, die ich kenne, was jedoch nicht heißt, dass es keine gibt ;)

MfG
Fabsch
 
Nunja, wenn ich es im BackgroundWorker starte, wird die BackgroundWorker erst abgeschlossen, wenn das Fenster geschlossen wird. Auserdem sind dann noch nicht alle Daten für das Fenster bearbeitet (XML-Dateien, Fenster läst die selbst ein).

Werde deine Methode mal ausprobieren, wenn nicht e ich es etwas um (hab schon eine Idee).
 
Zurück