ProgressBar with Timer

0

I have an application with a SplashScreen where I have ProgressBar barraProgresso . The goal is that once it is 100% loaded, open another form and close the Splash.

The problem is that when there is a 20% to complete, the window will lock, open the next form and soon after it closes the application as well.

Code:

private void timer1_Tick(object sender, EventArgs e)
    {
        if (barraProgresso.Value != 100)
        {
            barraProgresso.PerformStep();
        }
        else
        {
            timer1.Stop();
            new FormOpcaoAcesso().Visible = true;
            this.Close();
        }
    }

    private void SplashScreen_Load(object sender, EventArgs e)
    {
        timer1.Enabled = true;
        timer1.Start();
        timer1.Interval = 20;
        barraProgresso.Maximum = 100;
        barraProgresso.Step = 1;
        timer1.Tick  += new EventHandler(timer1_Tick);
    }

It's worth remembering that I really want to close the splash, and not give a .Hide() , for example.

    
asked by anonymous 09.06.2018 / 21:34

1 answer

1

So, you two problems there:

  • The bar to load in ~ 80% and already runs as if full.
  • Closing the splash screen also closes the main thread (resulting in closing all processes involved).
  • The problem 1. "has no solution", this is how windows was built. What happens is that the animation of the filling bar takes longer to reach 100% than the .Value of it itself. That is, if it has .Value = 0 , and you assign .Value to 100, it will take something like 1 second to arrive visually at 100%.

    This is exactly what is happening with the timer, it puts the bar at 100%, but the animation is still at 80%, however, since its value is already 100%, it still runs the code you wrote.

    To solve this, you can create an asynchronous method that gives a delay of about 1000 milliseconds and then open the new form:

    private async void RunAsync()
    {
        await Task.Delay(1000);
    
        new FormOpcaoAcesso().Show();
        this.Close(); // Ainda vai fechar o programa
    }
    

    And call this method asynchronous Tick .

    The 2. problem is simpler. The problem, as pointed out by the Rovann Linhalis , is that Form SplashScreem is the main program. To resolve this, go to Program.cs and edit the .Run method call so that instead of running Form , it runs with ApplicationContext . But you'll want this ApplicationContext to be accessible from other classes, so I'll suggest you create it as a public static property with get public and private set.

    The code that will be in Program.cs will be type like this:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
    
        App = new ApplicationContext();
        App.MainForm = new SplashForm();
    
        Application.Run(App);
    }
    
    public static ApplicationContext App { get; private set; }
    

    Then when you close the splash screen:

    //esse pedaço de código vai dentro da Form que você quer fechar (no caso a SplashScreen)
    private async void RunAsync()
    {
        await Task.Delay(1000);
    
        var form = new FormOpcaoAcesso();
        form.Show();
    
        Program.App.MainForm = form;
        this.Close();
    }
    

    Done: D Your two issues are resolved, remembering that using a delay is usually not a good idea, because it is not reliable that all the computers your program is running can execute the code at the right time. And I still think that you are cheating the user that neither Marchelo Uchimura commented and this is not cool guy, kk if it was a request of the teacher, try to give a function to the splash screen or make it very fast kkk. / p>     

    10.06.2018 / 14:49