-2

In C# im trying to make a little game type program and im trying to make a loading bar that uses the Progress bar and the text is using a Label, for example the Progress bar is 1 - 25 and i want the label text to update while the bar is, heres an example:

    private void StartLoading_Click(object sender, EventArgs e)
    {
        MainProgressBar.Maximum = 25;
        int P = 0;
        while (P < 25)
        {
            // Delay
            System.Threading.Thread.Sleep(130);
            // Increase Progress
            P++;
            // Set Progress Bar Value
            MainProgressBar.Value = P;
            // Set Text Above Progress Bar
            LoadingText.Text = P + "/25";
        }
    }

Ps. I dont want some Huge code, i want it to be simple like this

ZerterCodes
  • 73
  • 1
  • 1
  • 11
  • Try searching, don't block the UI thread, use a backgroundworker. Yes, that's "huge code", but it's necessary. – CodeCaster Jan 12 '17 at 12:18
  • When you update your controls in GUI thread, most controls will not process messages (because, they got the messages only after the execution ends). You should use a worker thread. The second method (processing messages) is not recommended. Progress bar has a different processing system, therefore it works like expected, but it is mostly an exception in graphical controls. – Julo Jan 12 '17 at 12:19
  • Make two properties in your viewmodel, one for the max value, and one for the current value, then bind to both values in your view. – LordWilmore Jan 12 '17 at 12:19
  • Putting a `Thread.Sleep` on your UI thread will create an unusable application. Look into using delegates and do it properly. – Chris Pickford Jan 12 '17 at 12:19
  • 1
    I know what i'm about to say is not popular, but for such a simple thing...try to add `Application.DoEvents();` after `LoadingText.Text = P + "/25";` – Pikoh Jan 12 '17 at 12:20
  • Thanks @Pikoh That worked Perfectly – ZerterCodes Jan 12 '17 at 12:23
  • You're welcome. But now every one here hates me ;) – Pikoh Jan 12 '17 at 12:24
  • @ZerterCodes Yes it works. But with this code you can cause many problems. Therefore I did not mention it. You should make some changes to your code to prevent these problems (like when two times click to the button). (P.S. Don't worry Pikoh, I don't hate you) – Julo Jan 12 '17 at 12:29
  • @Julo of course this is absolutely not the way of doing this. But it seems just a simple example, that's why i suggested `DoEvents`. OP may later find what are the problems of this implementation – Pikoh Jan 12 '17 at 12:34

1 Answers1

2

State of the art is this snippet for you:

private void StartLoading_Click(object sender, EventArgs e)
    {
        const int max = 25;
        var progressHandler = new Progress<int>(value=>{
            LoadingText.Text = value + "/" + max;
            MainProgressBar.Value = value;
        });

        var progress = progressHandler as IProgress<int>;
        await Task.Run(() =>
        {
           int P = 0;
           while (P < 25)
           {
              Thread.Sleep(130);
              progress?.Report(++P);
           }
        }       
    }

This processes your long running task (Sleep in this case), in a seperate Thread and reuse the value via the Progress-Class. This way your GUI is updated in GUI-Thread as recommended and you will get the updates accordingly. Further it's not recommended to use Application.DoEvents();, because there are many pitfalls you have to know about.

Community
  • 1
  • 1
Sebi
  • 3,879
  • 2
  • 35
  • 62
  • Where does it says _Application.DoEvents() This is just for backwardcompatibilty and shouldn't be used_? Not [here](https://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents(v=vs.110).aspx) at least :) – Pikoh Jan 12 '17 at 12:46
  • @Pikoh I updated my answer and corrected it. It comes from VB 5.X but seems to be ok in .Net as well. There are just many pitfalls you have to know and avoid: http://stackoverflow.com/questions/5181777/use-of-application-doevents – Sebi Jan 12 '17 at 12:58
  • That's better. Anyway, i'll also recomend reading [this link](https://blog.codinghorror.com/is-doevents-evil/) that basically tells the same i've already told in my comments: for simple cases as the one in OP sample, using `DoEvents()` is perfectly right. – Pikoh Jan 12 '17 at 12:59