使用Button-Paint-Event,for循环的每次迭代都不会更新Button。但是每次迭代都会平滑更新表单或面板。
因此,在执行此代码时,Button以默认颜色开始,然后在for循环结束后,显示colors-Array中的最后一种颜色。每次迭代都不会更新。
我的问题:有人知道,为什么按钮不会随每次迭代更新,但其他控件使用相同的代码?
void Main()
{
Color[] colors = new Color[10]
{
Color.White, Color.Red, Color.Blue, Color.Green, Color.Black,
Color.Purple, Color.Brown, Color.Yellow, Color.Gray, Color.Lime
};
Button button = new Button();
button.FlatStyle = FlatStyle.Flat;
button.Paint += (sender, e) =>
{
for (int i = 0; i < 10; i++)
{
e.Graphics.FillRectangle(
new SolidBrush(colors[i]),
new RectangleF(0, 0, button.Width, button.Height));
Thread.Sleep(100);
Application.DoEvents();
}
};
Form form = new Form();
form.Controls.Add(button);
form.Show();
}
我的问题:有人知道,为什么按钮不会随每次迭代更新,但其他控件使用相同的代码?
不知道
不过,你的方法有缺陷。你不应该在主UI线程中使用Sleep(),因为它可能导致无响应的UI。此外,对DoEvents()的调用可能导致更多的Paint()事件发生(重入代码)。
使用Timer控件并从那里更改Button的BackColor。
这是一个使用Enumerator重复循环颜色的简单示例:
static void Main()
{
Color[] colors = new Color[10]
{
Color.White, Color.Red, Color.Blue, Color.Green, Color.Black,
Color.Purple, Color.Brown, Color.Yellow, Color.Gray, Color.Lime
};
IEnumerator colorEnum = colors.GetEnumerator();
Button button = new Button();
button.FlatStyle = FlatStyle.Flat;
System.Windows.Forms.Timer tmr = new System.Windows.Forms.Timer();
tmr.Interval = 250;
tmr.Tick += (s, e) =>
{
if (!colorEnum.MoveNext())
{
colorEnum.Reset();
colorEnum.MoveNext();
}
button.BackColor = (Color)colorEnum.Current;
};
Form form = new Form();
form.Shown += (s, e) =>
{
tmr.Start();
};
form.Controls.Add(button);
Application.Run(form);
}