简体   繁体   English

Windows窗体应用程序-启动屏幕标签未更新

[英]Windows Form Application - Splash screen label not updating

I have a windows form application which is supposed to show a splash screen with a label field that I want to update as the main form (called welcome.cs) loads in the background. 我有一个Windows窗体应用程序,该应用程序应该显示一个带有我要更新的标签字段的初始屏幕,因为主窗体(称为welcome.cs)在后台加载。 The splash screen shows & hides just fine, but the label doesn't update. 初始屏幕显示并隐藏得很好,但标签不会更新。

I've done a lot of research but haven't quite found the solution. 我已经做了很多研究,但是还没有找到解决方案。

Program.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 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 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.....
}

Does it have something to do with multi-threading or is it because im creating a new instance of splashscreen in welcome.cs before calling UpdateStatus? 它与多线程有关吗?或者是因为我在调用UpdateStatus之前在welcome.cs中创建了一个初始屏幕的新实例? How would I get around this? 我该如何解决?

You could do the following 您可以执行以下操作

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

Note that you will need to create a method called AtualizarMensagem(string str) in your splash screen form, like this 请注意,您将需要在初始屏幕表单中创建一个名为AtualizarMensagem(string str)的方法,如下所示

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

I have this code in my "useful snnipets" folder, it always works for me. 我的“有用的摘要”文件夹中有此代码,它始终对我有用。 Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM