2009-09-01 5 views
1

Ok, je sais que cela a été demandé un million de fois auparavant (et les gens commencent aussi leur question StackOverflow de la même façon XD), mais je voudrais savoir comment atteindre les résultats suivants:Une exigence différente pour un écran de démarrage dans l'application winforms

  1. la première application lance une boîte de connexion
  2. Si la connexion est réussie, l'écran de démarrage doit montrer (sur un thread séparé).
  3. Lorsque l'écran de démarrage est affiché, un objet de classe doit être rempli (qui adhère au motif Singleton) avec des quantités importantes de données spécifiques à l'utilisateur du DB, tout en affichant à l'utilisateur ce qu'il fait (par exemple initialisation. ..loading data ... préférences de chargement ... renderplay workspace ... done!)
  4. L'écran de démarrage doit également attendre que le formulaire principal ait fini de s'initialiser sur le thread principal, avant d'être finalement éliminé.

C'est le flux de désir pour l'application. Lors de la fermeture du formulaire principal, l'utilisateur doit être renvoyé à la boîte de connexion.

Je dois dire d'emblée que je ne suis pas tout à fait d'accord avec beaucoup de choses sur les winforms, mais en posant ce genre de questions, j'apprends lentement. J'ai fait quelques lectures sur le threading, et j'ai appris que l'écran de démarrage devrait apparaître dans son propre thread, et alimenter les mises à jour en utilisant des délégués (pour gérer les mises à jour de l'interface utilisateur) du thread principal. cela devrait être fait dans le sous-programme Program.cs "Main()".

J'arrive ici, car je ne sais même pas par où commencer, en raison de l'exigence supplémentaire d'avoir le formulaire de connexion en premier (et ensuite en dernier lorsque le formulaire principal est fermé). J'apprécierais certainement toute aide à cet égard.

Merci beaucoup! sha

Répondre

2

Voici un exemple simple de la façon de procéder. L'astuce consiste à faire de la boîte de connexion votre formulaire principal puisque c'est celui qui s'ouvre en premier et se ferme en dernier.

Pour cet exemple, le formulaire LoginScreen possède un bouton, un bouton OK qui invoque la méthode OnOK() lorsque vous cliquez dessus.

public partial class LoginScreen : System.Windows.Forms.Form 
{ 
    ApplicationWindow window; 

    public LoginScreen() 
    { 
     InitializeComponent(); 
    } 
    private void OnFormClosed(object sender, FormClosedEventArgs e) 
    { 
     this.Show(); 
    } 
    private void OnOK(object sender, EventArgs e) 
    { 
     this.Hide(); 

     window = new ApplicationWindow(); 
     window.FormClosed += OnFormClosed; 
     window.Show(); 
    } 
} 

Le formulaire ApplicationWindow équivaudrait à ce que vous appelez votre formulaire "principal". C'est ce qui lance le SplashForm.

public partial class ApplicationWindow : System.Windows.Forms.Form 
{ 
    public ApplicationWindow() 
    { 
     SplashForm.Show(500); 

     InitializeComponent(); 
    } 

    private void OnLoad(object sender, EventArgs e) 
    { 
     // Simulate doing a lot of work here. 
     System.Threading.Thread.Sleep(1000); 

     SplashForm.Hide(); 

     Show(); 
     Activate(); 
    } 
} 

Et voici une copie du SplashForm que j'utilise. Il va fondre et fondu en fonction du nombre de millisecondes que vous spécifiez dans la méthode statique Show().

public partial class SplashForm : Form 
{ 
    #region Public Methods 

    /// <summary> 
    /// Shows the splash screen with no fading effects. 
    /// </summary> 
    public new static void Show() 
    { 
     Show(0); 
    } 

    /// <summary> 
    /// Shows the splash screen. 
    /// </summary> 
    /// <param name="fadeTimeInMilliseconds">The time to fade 
    /// in the splash screen in milliseconds.</param> 
    public static void Show(int fadeTimeInMilliseconds) 
    { 
     // Only show the splash screen once. 
     if (_instance == null) { 
      _fadeTime = fadeTimeInMilliseconds; 
      _instance = new SplashForm(); 

      // Hide the form initially to avoid any pre-paint flicker. 
      _instance.Opacity = 0; 
      ((Form) _instance).Show(); 

      // Process the initial paint events. 
      Application.DoEvents(); 

      if (_fadeTime > 0) { 
       // Calculate the time interval that will be used to 
       // provide a smooth fading effect. 
       int fadeStep = (int) Math.Round((double) _fadeTime/20); 
       _instance.fadeTimer.Interval = fadeStep; 

       // Perform the fade in. 
       for (int ii = 0; ii <= _fadeTime; ii += fadeStep) { 
        Thread.Sleep(fadeStep); 
        _instance.Opacity += 0.05; 
       } 
      } else { 
       // Use the Tag property as a flag to indicate that the 
       // form is to be closed immediately when the user calls 
       // Hide(); 
       _instance.fadeTimer.Tag = new object(); 
      } 

      _instance.Opacity = 1; 
     } 
    } 

    /// <summary> 
    /// Closes the splash screen. 
    /// </summary> 
    public new static void Hide() 
    { 
     if (_instance != null) { 
      // Invoke the Close() method on the form's thread. 
      _instance.BeginInvoke(new MethodInvoker(_instance.Close)); 

      // Process the Close message on the form's thread. 
      Application.DoEvents(); 
     } 
    } 

    #endregion Public Methods 

    #region Constructors 

    /// <summary> 
    /// Initializes a new instance of the SplashForm class. 
    /// </summary> 
    public SplashForm() 
    { 
     InitializeComponent(); 

     Size = BackgroundImage.Size; 

     // If transparency is ever needed, set the color of the desired 
     // transparent portions of the bitmap to fuschia and then 
     // uncomment this code. 
     //Bitmap bitmap = new Bitmap(this.BackgroundImage); 
     //bitmap.MakeTransparent(System.Drawing.Color.Fuchsia); 
     //this.BackgroundImage = bitmap; 
    } 

    #endregion Constructors 

    #region Protected Methods 

    protected override void OnClosing(CancelEventArgs e) 
    { 
     base.OnClosing(e); 

     // Check to see if the form should be closed immediately. 
     if (fadeTimer.Tag != null) { 
      e.Cancel = false; 
      _instance = null; 
      return; 
     } 

     // Only use the timer to fade if the form is running. 
     // Otherwise, there will be no message pump. 
     if (Application.OpenForms.Count > 1) { 
      if (Opacity > 0) { 
       e.Cancel = true; // prevent the form from closing 
       Opacity -= 0.05; 

       // Use the timer to iteratively call the Close method. 
       fadeTimer.Start(); 
      } else { 
       fadeTimer.Stop(); 

       e.Cancel = false; 
       _instance = null; 
      } 
     } else { 
      if (Opacity > 0) { 
       Thread.Sleep(fadeTimer.Interval); 
       Opacity -= 0.05; 
       Close(); 
      } else { 
       e.Cancel = false; 
       _instance = null; 
      } 
     } 
    } 

    #endregion Protected Methods 

    #region Private Methods 

    private void OnTick(object sender, EventArgs e) 
    { 
     Close(); 
    } 

    #endregion Private Methods 

    #region Private Fields 

    private static SplashForm _instance = null; 
    private static int _fadeTime = 0; 

    #endregion Private Fields 
} 

Le SplashForm est juste une forme vide avec les valeurs des propriétés suivantes:

  • BackgroundImage = (l'image de votre choix)
  • BackgroundImageLayout = Centre
  • DoubleBuffered = true
  • FormBorderStyle = Aucun
  • ShowInTaskbar = Faux
  • StartPosition = CenterScreen
  • TopMost = true

Il contient également un contrôle System.Windows.Forms.Timer nommé fadeTimer avec les propriétés par défaut. L'événement Tick est configuré pour appeler la méthode OnTick().

Ce que cela ne fait pas, c'est de mettre à jour le statut du processus de chargement. Peut-être que quelqu'un d'autre peut remplir cette partie pour vous.

+0

Cela ne génère pas le Splash Form dans un thread séparé, mais l'autre lien devrait aider avec cela. –

+0

Pour communiquer avec l'écran de démarrage, soit il écoute les événements sur ApplicationWindow, soit le processus de chargement appelle périodiquement les méthodes sur l'écran de démarrage. N'oubliez pas d'utiliser BeginInvoke si l'écran de démarrage est dans un fil séparé. –

+0

Vous avez raison. Cela fait un moment que j'ai regardé ce code. Je vais mettre à jour mon message pour être correct. Merci. –