Yes, in a way you're right (almost). When you change some control data, you need to invalidate it to put data in effect. Usually you do it via
Control.Invalidate
, but if this is a property like
Text
, a side effect of the property assignment (you should understand actually this can be a call to some setter method) is calling
<code>
Invalidate inside the setter.
Invalidation cause rendering to occur. Assuming you're talking about
System.Windows.Forms
, you form gets the message
WM_PAINT
, translated to firing of the
Paint
event. All the invalidated regions are ORed (in the sense of Set Theory for the point sub-sets of the control's client area) and the resulted region is re-rendered. If the data was changed, the view looks different.
As I understand, you want some king of animation — one step at a time. It is simple, if you want to click on some control for every step (button click or whatever). In this case you change data on every click.
If you need timed steps, you can do it using timer (I don't recommend it) in the same way. Better way is using some thread. Using
BackgroundWorker
is the easiest for your purpose.
Button myButton =
Label myLabel =
myButton.Click += (sender, eventArgs) => {
System.ComponentModel.BackgroundWorker worker =
new System.ComponentModel.BackgroundWorker();
worker.DoWork += (workerSender, workerEventArgs) => {
myLabel.Invoke(
new System.Action<Label>((label) => {
myLabel.Text = "Phase 1";
}), myLabel);
Thread.Sleep(500);
new System.Action<Label>((label) => {
myLabel.Text = "Phase 2";
}), myLabel);
Thread.Sleep(500);
};
};
It it important to understand, that in the thread other than UI thread UI property cannot be assigned directly. Inter-thread invocation should be used (pay attentions:
myLabel.Invoke
). UI thread is able to queue the request for the delegate changing the label and actually call the property on UI thread.
In real life,
myLabel.Text
should be sent in invocation as yet another parameter, whole invocation fragment abstracted out in a separate method, etc.
—SA