Button-Color仅在完成Paint-Method后更新

问题描述 投票:0回答:1

使用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();
}
c# forms button paint doevents
1个回答
0
投票

我的问题:有人知道,为什么按钮不会随每次迭代更新,但其他控件使用相同的代码?

不知道

不过,你的方法有缺陷。你不应该在主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);
}
© www.soinside.com 2019 - 2024. All rights reserved.