在winforms应用程序中对Splash Screen的不同要求

时间:2009-09-01 19:08:15

标签: c# winforms multithreading splash-screen

好的,我知道之前已经被问了一百万次(人们也以XD的方式开始了他们的StackOverflow问题),但我想知道如何实现以下目标:

  1. 应用程序首先启动登录框
  2. 如果登录成功,则必须显示启动画面(在单独的线程上)。
  3. 在显示启动画面时,必须使用来自DB的大量用户特定数据填充类对象(遵循Singleton模式),同时向用户显示其正在执行的操作(例如,初始化)。 .. loading data ... loading preferences ...渲染工作区......完成!)
  4. 启动画面还必须等待主窗体在主线程上完成初始化,然后再进行处理。
  5. 这是应用程序的愿望流程。关闭主表单后,用户应返回登录框。

    我必须事先声明我并不是所有关于winforms的东西,但通过提出这些问题,我正在慢慢学习。我一直在做一些关于线程的阅读,并且已经了解到应该在自己的线程中生成启动画面,并使用委托(以满足UI的跨线程更新)来提供状态更新,以及这应该都在 Program.cs “Main()”子程序中完成。

    我正在这里接触,因为我甚至不知道从哪里开始,因为需要首先显示登录表单(然后在主表单关闭时最后一次)。我当然会重视这方面的任何援助。

    非常感谢! 沙

1 个答案:

答案 0 :(得分: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 = Center
  • DoubleBuffered = true
  • FormBorderStyle =无
  • ShowInTaskbar = False
  • StartPosition = CenterScreen
  • TopMost = true

它还包含一个名为fadeTimer的System.Windows.Forms.Timer控件,其默认属性。 Tick事件配置为调用OnTick()方法。

这不做的是更新加载过程的状态。也许其他人可以为你填写那部分。