1

I have just started studying .Net Winform with C# (.Net 5). I did a simple winform with a NumericUpDown and a ProgressBar, basically, the ProgressBar will update its value when the NumericUpDown's value changes via the ValueChanged event.

Here is my code:

private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
   progressBar2.Value = (int)numericUpDown1.Value;
}

I notice that the ProgressBar update took about half a second to detect the NumericUpDown ValueChanged when the value is increasing (from 0 to 1, 1 to 2, 2 to 3, etc.) no matter whether I was holding the Up key to increase it continuously or press one at a time.

However, when the value is decreasing, the progress bar update instantly, even when I hold down the Down button to decrease it continuously. Which is pretty weird.

Even when I enter the value directly, it still does the same thing: enter 80 when it is at 20 took a bit to fill up while enter 20 when it is 80 update instantly

The most obvious way to see it is holding the Up button to continuously increasing the value and then press the Down key once. The Progress Bar fill up slowly and then suddenly jump to the correct value when the Down key is pressed

My question is: Is this the default behavior? Does Visual Studio had different algorithm to detect increase or decrease value change? Or am I missing something?

1
  • Visual Studio has nothing to do with this. -- The ProgressBar (a .Net component) has an animation that adds a delay (so it doesn't go up to the maximum immediately if the procedure that increases the value is very fast, so you don't see just a full bar). There's nothing to worry about it :) Commented Jun 22, 2022 at 4:22

1 Answer 1

2

I am pretty sure what you are seeing is the default behavior of the ProgressBar Control. When the progress bar increases, there is a small “delay” to show each step. I may be mistaken; however, I could not find any particular property in the ProgressBar control that would remove or shorten this “delay.”

Fortunately, I did find a fairly simple solution that appears to work. In this solution the idea is to “increase” the current value from the NUD by one (1). Then set the progress bars value to that value, then immediately change the progress bars value back to the true value.

The only issue is if the NUDS value is at the maximum of the progress bar. If we try and increase the NUDS value by 1, then we would go out of bounds on the progress bar. So, in that case we simply need to increase the progress bars maximum value by 1, set the value, then immediately set it back to the original maximum value.

See if the code below works as you are wanting. Please let me know as I will remove it if it does not work as you are wanting.

private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
  //progressBar1.Value = (int)numericUpDown1.Value;
  if ((int)numericUpDown1.Value == progressBar1.Maximum) {
    progressBar1.Maximum = progressBar1.Maximum + 1;
    progressBar1.Value = (int)numericUpDown1.Value + 1;
    progressBar1.Value = (int)numericUpDown1.Value;
    progressBar1.Maximum = progressBar1.Maximum - 1;
  }
  else {
    progressBar1.Value = (int)numericUpDown1.Value + 1;
    progressBar1.Value = (int)numericUpDown1.Value;
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

You can probably simply set int value = (int)nud.Value; pbar.Value = pbar.Maximum; if (value < pbar.Maximum) pbar.Value = value;
@Jimi … thanks for your input... using your code, it worked great except in ONE case… if the user entered the progress bars max value, then the progress is going to show the delay… but ONLY for the progress bars MAX value. Any value the user enters that is at least 1 less than the max, then it works as expected. In my small tests, it is unavoidable to check the NUDs value to the progress bars max value to avoid the “delay”…
The only way I could get it to work, was to increase the progress bars max value by 1, set its value then revert back. I am guessing the only reason this works at all is because after the value is set the first time, the next value set will ALWAYS be less than the current value and will not use the delay. But this is pure speculation on my part. I hope I have that right and am not missing something obvious.
Sure, I wasn't suggesting to change anything, it's just a different method (should be value <= ... instead of value < ...). -- If you want a suggestion (unsolicited :), you could use SendMessage to send a PBM_DELTAPOS = 0x0403 message to the ProgressBar. The message returns the previous position. You have to store the previous position, then the code can be: private int prev = 0; //[...] // In the handler: prev = (int)nud.Value - prev; prev = SendMessage(pBar.Handle, PBM_DELTAPOS, prev, 0); -- This has no animation. The Style should be set to Continuous
So, maybe in a Custom Control, you could expose a Property that allow to specify, e.g., public bool Animate {get; set; }. Use the default method if true, the PBM_DELTAPOS method if false

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.