Laden...

Splash Screen - MainForm im Hintergrund

Erstellt von trib vor 8 Jahren Letzter Beitrag vor 8 Jahren 3.733 Views
T
trib Themenstarter:in
708 Beiträge seit 2008
vor 8 Jahren
Splash Screen - MainForm im Hintergrund

Hallo zusammen,

ich verwende in einer Forms Anwendung einen Splash-Screen.
Dieser startet vor der MainForm in der Program.cs Main():

SplashScreen.Splash.StartSplash();
Application.Run(new StartupForm());

Darin wird die Form in einem separaten Thread aufgerufen:

public static void StartSplash()
        {
            // Create a new thread from which to start the splash screen form
            var splashThread = new Thread(StartSplashForm) {IsBackground = true, Priority = ThreadPriority.Highest};
            splashThread.Start();            

            while (!_splashForm.Loaded)
            {
                Thread.Sleep(10);
            }
        }

Nun wird in der StartupForm, am ende des Load-Events, das Schließen des Spash-Fensters aufgerufen:

 private void StartupForm_Load(object sender, EventArgs e)
        {
            TopMost = true;
            SplashScreen.Splash.CloseSplash();
            TopMost = false;
            Activate();
            Focus();
        }

Das klappt soweit auch, allerdings:
Die Form erscheint auch über z.B. dem Explorer, erhält aber keinen Fokus.
Per Alt-Tab sieht man, dass die Form ganz am Ende der Fenster-Kette steht.

Rufe ich während dem Startvorgang ein Modales Fenster auf (weil eine Einrichtung fehlt) so landet dies komplett im Hintergrund.

Es ist irrelevant, ob ich den Thread des Splash-Fensters auf IsBackground true oder false setze.
Wie kann ich trotz des SplashScreens dafür sorgen, dass die Haupt-Form nun nach dem Start in den Vordergrund rückt?

D
171 Beiträge seit 2008
vor 8 Jahren

Hallo trib,


MainForm.BringToFront();

nachdem dein Splashscreen durchgelaufen ist. Beachte bei Bedarf invoke

C
168 Beiträge seit 2010
vor 8 Jahren

Kurze Anmerkung

            while (!_splashForm.Loaded)
            {
                Thread.Sleep(10);
            }

Thread.Sleep ist meiner Meinung nach ein Workaround für Problem die man nicht sauber lösen kann. Verwende einen Custom EventHandler oder ein Delegate, diesen/dieses rufst du auf wenn der Ladevorgang abgeschlossen ist, dadruch sollte die schleife unnötig sein.

Real programmers don't comment their code - it was hard to write, it should be hard to understand.

T
trib Themenstarter:in
708 Beiträge seit 2008
vor 8 Jahren

Hallo trib,

  
MainForm.BringToFront();  
  

nachdem dein Splashscreen durchgelaufen ist. Beachte bei Bedarf invoke

Hallo Daniel,
danke für Deine Antwort. Leider erziehle ich auch damit nicht den gewünschten Effekt. Das Fenster ist optisch zwar im Vordergrund, jedoch nicht fokussiert und es blinkt in der Taskleiste.

Kurze Anmerkung

            while (!_splashForm.Loaded)  
            {  
                Thread.Sleep(10);  
            }  

Thread.Sleep ist meiner Meinung nach ein Workaround für Problem die man nicht sauber lösen kann. Verwende einen Custom EventHandler oder ein Delegate, diesen/dieses rufst du auf wenn der Ladevorgang abgeschlossen ist, dadruch sollte die schleife unnötig sein.

Hallo Crone.
Ja, das ist korrekt. Das war ein Workaround um auch unter Windows CE im Compact Framework zu laufen. Habe aber gerade gesehen, dass ich keine nachgelagerte Funktion mehr dahinter habe. Also kann das ohnehin raus 😃

C
168 Beiträge seit 2010
vor 8 Jahren

Ich erzeuge einen SplashScreen immer folgendermaßen:

  1. MainForm Konstruktor ausführen
  2. Im Konstruktor als erstes this.Hide ausführen
  3. Im Konstruktor als zweites SplashScreen erzeugen und mit Show und BringToFront anzeigen
  4. Im Konstruktor einen neuen Thread erzeugen in dem dein Ladevorgang stattfindet.
  5. Wenn Ladevorgang beendet SplashScreen.Hide und this.Show ausführen.

Damit solltest du einen Funktionierenden SplashScreen bekommen.

Real programmers don't comment their code - it was hard to write, it should be hard to understand.

T
trib Themenstarter:in
708 Beiträge seit 2008
vor 8 Jahren

Tja, das klingt ja alles sehr Logisch und ich denke so weit war ich mit meinem Code auch nicht davon entfernt... Aber es funktioniert genau so!!!
Vielen Dank 😃

Die BringToFront()´s scheinen alle überflüssig zu sein.
Es liegt wohl wirklich am Hide -> SplashScreen starten -> Show -> Activate(). (Activate brauche ich damit das 1. Control fokussiert wird.)

Nun kann ich auch auf die ganzen TopMost, BringToFront & Focus verzichten.
Meine Theorie: Mainform startet, kommt durch den Splashscreen in den Hintergrund. Splash wird geschlossen und die Mainform bleibt in 2. Reihe.
Durch das Show, ändert sich das Verhalten und die Form wird vor den Splashscreen gelegt.

3.003 Beiträge seit 2006
vor 8 Jahren

Schau dir das Tutorial hier mal an:

A Pretty Good Splash Screen in C#

Das lässt nicht viel zum Thema "Splashscreen" übrig 😉.

Dein Problem würde ich an der Stelle vermuten, wo du vor der Initialisierung der UI (Application.Run) bereits UI-Elemente nutzt. Das kann nicht gut gehen.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

4.931 Beiträge seit 2008
vor 8 Jahren

Der Fehler liegt vorallendingen dardrin, den Splashscreen in einem eigenen Thread laufen zu lassen!

trib, schau dir einfach mal die beiden Snippets SplashScreen-Komponente (noch eine ;-P) sowie Yet another SplashScreenHelper an.

F
10.010 Beiträge seit 2004
vor 8 Jahren

Warum benutzt eigentlich keiner die im FW eingebauten Möglichkeiten?
WindowsFormsApplicationBase.SplashScreen Property

Man muss übrigens die Windows Version nicht verstümmeln nur weil irgendwas anderes auch auf CF laufen muss