0

使用 Button-Paint-Event 按钮不会在 for 循环的每次迭代中更新。但是每次迭代都会平滑地更新表单或面板。

因此,在执行此代码时,Button 以默认颜色开始,然后在 for 循环完成后,显示颜色数组中的最后一种颜色。它不会随着每次迭代而更新。

我的问题:有人知道,为什么每次迭代都没有更新 Button,但其他控件使用相同的代码?

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();
}
4

1 回答 1

0

我的问题:有人知道,为什么每次迭代都没有更新 Button,但其他控件使用相同的代码?

不知道。

不过,您的方法一开始就有缺陷。您永远不应该在主 UI 线程中使用 Sleep(),因为它可能导致 UI 无响应。此外,对 DoEvents() 的调用可能会导致更多 Paint() 事件发生(可重入代码)。

使用Timer控件并从那里更改 Button 的BackColor 。

这是一个使用枚举器重复循环颜色的简单示例:

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);
}
于 2019-03-17T15:10:08.487 回答