Here is what I found:
Add this method to the form:
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
}
Make maximum big enough (on both progress bar and cycle), to give youself enough time.
After button press, put a break point at the first statement
base.WndProc(ref m)
. You will see that the messages are pumped. And it won't happen when you replace assignment of the progress bar
Value
with, say,
ListBox
operations, as I suggested in my comment to the question.
So, here is how I can explain it: this property assignment does something special. What? On a next step, I checked up it if calls
Application.DoEvents
. No, it doesn't. I checked it up by updating
both ListBox
and
ProgressBar
. List view is still not rendered. When you use, for comparison,
Application.DoEvents
(commented out), you can see that list box items are rendered, as I expected.
using System;
using System.Windows.Forms;
using System.Threading;
public partial class MainForm {
ProgressBar pb = new ProgressBar();
Button btn = new Button();
ListBox lb = new ListBox();
const int max = 100;
public MainForm() {
btn.Dock = DockStyle.Top;
pb.Dock = DockStyle.Bottom;
pb.Maximum = max;
lb.Dock = DockStyle.Right;
btn.Parent = this;
pb.Parent = this;
lb.Parent = this;
btn.Click += (sender, eventArgs) => {
for (int i = 0; i < max; i++) {
lb.Items.Add(i);
pb.Value = i;
Thread.Sleep(100);
}
};
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
}
}
So, I can make a conclusion that the
ProgressBar.Value
assignment, in addition to invalidation, does something to pump specific messages through the message queue. Probably, it pumps only the messages specific to
ProgressBar
. What exactly? Since this moment, I lost interest to the "problem": you can find out further detail if you spy on all messages, or something like that. Anyway, I cannot see anything miraculous now. By the way, the sample code for effective spying could be found in my article on a completely different topic:
Dynamic Method Dispatcher.
[EDIT]
And yes, we observed that the scroll bar is refreshed, in contrast to the
TreeView
content. It could be explained in the same way, if not one problem: I could not observe message pumping. Anyway, your question was about
ProgressBar
only. Some more investigation could be done for some other cases. ;-)
[END EDIT]
Now, the question is: why is it so? I would speculate that this functionality addresses the problem of alleviating lamers' problems: the progress bar could be designed the way it "refreshes no matter what", not matter what kind of misuse one could do to it. How about this idea?
—SA