Progressbar with Timer

Asked

Viewed 185 times

0

I have an app with a Splashscreen where I have the 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% missing to complete, the window hangs, opens the next form and immediately after it closes, also closing the application.

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

Remember that I really want to close the splash, and not give a .Hide(), for example.

  • 2

    Basically, you want to cheat the user?

  • 2

    "the system is opening too fast, I will put a bar only to delay it" rsrs but then... likely that your Splash is the main form of the application, have to see the code from the main method to the form that should be open

1 answer

1


So you two trouble there:

  1. The slider stops pressing ~80% and already runs as if it was full.
  2. Close the splashscreen also closes the main thread (resulting in the closure of all processes involved).

The problem 1. "has no solution", that’s how windows was built. What happens is that the animation of the filling bar takes longer to reach 100% than the .Value of her in you. That is, if she is with .Value = 0, and you assign the .Value for 100, it will take something like 1 second to reach, visually, the 100%.

That’s exactly what’s happening with the timer, it puts the bar at 100%, but the animation is still at 80%, however, as its value is already 100%, it keeps running 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 that asynchronous method of your method Tick.

Already the problem 2. is simpler. The problem, as pointed out by Rovann Linhalis, is that the Form Splashscreem is the main of the program. To resolve this, go to the file Program.cs and edit the method call .Run so that instead of rotating with a Form, he rides with a ApplicationContext. However you will want this Applicationcontext to be accessible from other classes, so I will suggest that you create it as a Static public property with get public and private set.

The code that will be on Program.cs it’s gonna be 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 splashscreen:

//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 problems are solved, remembering that using a delay is usually not a good idea, because it is not reliable that all the computers that your program is running can run the code at the right time. And I still think you’re fooling the user that not even Marchelo Uchimura commented and this is not cool dude, kk if it was a request from the teacher(a), tries to give a function to the screen splash or make it very fast kkk.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.