Windows窗体应用程序 - 不更新初始屏幕标签

时间:2015-06-11 02:11:37

标签: c# winforms splash-screen

我有一个Windows窗体应用程序,它应该显示一个带有标签字段的启动画面,我希望在后台加载主窗体(称为welcome.cs)时更新。启动画面显示&隐藏得很好,但标签没有更新。

我做了很多研究,但还没有找到解决方案。

Program.cs

/// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        using (new SingleGlobalInstance(1000))
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            SplashScreen splashscreen = new SplashScreen();
            splashscreen.ShowSplashScreen();

            Welcome welcome = new Welcome(splashscreen); //Takes some time to load
            splashscreen.CloseForm();
            Application.Run(welcome);

        }
    }

Splashscreen.cs

public partial class SplashScreen : Form
    {
        //Delegate for cross thread call to close
        private delegate void CloseDelegate();
        private delegate void UpdateStatusDelegate(string status);
        private static SplashScreen splashScreen;
        private Thread thread = null;

        public SplashScreen()
        {
            InitializeComponent();
        }

        public void ShowSplashScreen()
        {
            // Make sure it is only launched once.

            if (splashScreen != null)
                return;
            thread = new Thread(ShowForm);
            thread.IsBackground = true;
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        static private void ShowForm()
        {
            splashScreen = new SplashScreen();
            Application.Run(splashScreen);
        }

        public void CloseForm()
        {
            splashScreen.Invoke(new CloseDelegate(CloseFormInternal));
        }

        static private void CloseFormInternal()
        {
            splashScreen.Close();
        }

        public void UpdateStatus(string status)
        {
            splashScreen.Invoke(new UpdateStatusDelegate(UpdateStatusInternal), status);
        }

         private void UpdateStatusInternal (string status)
        {
             if (splashScreen != null && splashScreen.IsHandleCreated)
             {
                 lblStatus.Text = status;
             }

        }
    }

Welcome.cs

public Welcome(Splashscreen splashscreen)
{
        InitializeComponent();
        //Code to log the user into the system

        splashScreen.UpdateStatus("Logging in...");
        //my expectation is that UpdateStatus call will update the label displayed on the splash screen but it doesn't.

        //Do more stuff.....
}

是否与多线程有关或是因为我在调用UpdateStatus之前在welcome.cs中创建了一个新的splashscreen实例?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您可以执行以下操作

 static void Main()
 {
     Application.EnableVisualStyles();
     Application.SetCompatibleTextRenderingDefault(false);

     string[] args = Environment.GetCommandLineArgs();

     // Creates the Splash
     splash = new FrmSplash();

     //Opens the Splash in a new Thread, this way any gifs, progress bars, lablels changes will work because the main thread isnt blocked
     var t = Task.Factory.StartNew(() =>
     {
         splash.ShowDialog();
     });

      while (!splash.Created) // wait the splash screen form load process
          System.Threading.Thread.Sleep(300);

     UpdateSplashMessage("Loading the program... Please wait");         
     // Some slow initialization code.
     // ...

     //Close splash screen
     CloseSplash();

     Application.Run(args);
 }

 static void CloseSplash()
 {
     splash.Invoke(new MethodInvoker(() =>
     {
         splash.Close(); // Closes the splash that is running in the other thread
     }));
 }

 static void UpdateSplashMessage(string msg)
 {
     splash.Invoke(new MethodInvoker(() =>
     {
         splash.AtualizarMensagem(msg);
     }));
 }

请注意,您需要在初始屏幕窗体中创建一个名为AtualizarMensagem(string str)的方法,如下所示

public void AtualizarMensagem(string novaMsg)
{
    lblCarregando.Text = novaMsg;
}

我在我的&#34;有用的snnipets&#34;中有这个代码。文件夹,它总是适合我。 希望这会有所帮助。