2009-09-01 3 views
1

Хорошо, я знаю, что это задавали миллион раз раньше (и люди также начинают свой вопрос StackOverflow тем же самым способом XD), но я хотел бы знать, как достижение следующих целей:Другое требование для экрана Splash в winforms app

  1. Приложение первым запускает поле Логин
  2. Если Войти успешно, то на экране выплеска должен показать (в отдельном потоке).
  3. Пока отображается экран заставки, объект класса должен быть заполнен (который придерживается шаблона Singleton) с обильным количеством данных, специфичных для пользователя, из базы данных, показывая пользователю, что он делает (например, инициализация. .. загрузка данных ... загрузка предпочтений ... рендеринг рабочего пространства ... сделано!)
  4. Заставка должна также дождаться, когда основная форма завершит инициализацию основного потока, прежде чем, наконец, будет удалена.

Это поток желания для приложения. При закрытии основной формы пользователь должен быть возвращен в поле входа.

Я должен заранее заявить, что я не все, что связано с большим количеством материалов winforms, но, задавая такие вопросы, я медленно учусь. Я занимаюсь чтением по потокам и узнал, что всплывающий экран должен быть создан в своем потоке, а также обновлять статус фида, используя делегаты (для поддержки сквозных обновлений для пользовательского интерфейса) из основного потока, и что все это должно быть сделано в программе Program.cs «Main()».

Я обращаюсь к вам здесь, так как я даже не знаю, с чего начать, из-за дополнительного требования сначала иметь форму входа в систему (а затем последний, когда основная форма закрыта). Разумеется, я бы оценил любую помощь в этом отношении.

Большое спасибо! sha

ответ

2

Вот простой пример того, как это сделать. Хитрость заключается в том, чтобы сделать логин вашей главной формой, так как она открывается первой и закрывается последней.

Для этого примера форма LoginScreen имеет одну кнопку, кнопку OK, которая вызывает метод OnOK() при нажатии.

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(); 
    } 
} 

Форма ApplicationWindow будет равна тому, что вы назвали своей «основной» формой. Это то, что запускает 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(); 
    } 
} 

И вот копия SplashForm, которую я использую. Он будет исчезать и исчезать в зависимости от количества миллисекунд, заданных в статическом методе 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 
} 

SplashForm просто пустая форма со следующими значениями свойств:

  • BackgroundImage = (изображение по вашему выбору)
  • BackgroundImageLayout = Центр
  • DoubleBuffered = истинный
  • FormBorderStyle = None
  • ShowInTaskbar = False
  • StartPosition = CenterScreen
  • TopMost = истинный

Он также содержит элемент управления System.Windows.Forms.Timer именем fadeTimer со свойствами по умолчанию. Событие Tick настроено на вызов метода OnTick().

Что это не значит, это обновить статус процесса загрузки. Возможно, кто-то другой может заполнить эту часть для вас.

+0

Это не запускает форму Splash в отдельном потоке, но другая ссылка должна помочь с этим. –

+0

Для связи с экраном заставки либо он прослушивает события в ApplicationWindow, либо процесс загрузки периодически вызывает методы на заставке. Не забудьте использовать BeginInvoke, если заставка включена в отдельный поток. –

+0

Ты прав. Прошло некоторое время с тех пор, как я просмотрел этот код. Я буду обновлять сообщение, чтобы оно было правильным. Благодарю. –