【问题标题】:Change Form color constantly不断改变表格颜色
【发布时间】:2015-08-06 13:31:33
【问题描述】:

我希望我的程序不断更改字体背景颜色,但我希望它顺利进行,所以我尝试修改颜色变量 Color custom; 并将其用于表单 this.BackColor = custom; 的背景颜色,但它没有'不工作,我不知道如何使它工作,这是完整的代码:

private void Principal_Load(object sender, EventArgs e)
{
    Color custom;
    int contr = 0, contg = 0, contb = 0;
    do
    {
            while (contr < 255 && contg == 0)
            {
                if (contb != 0)
                {
                    contb--;
                }
                contr++;
                while (contg < 255 && contb == 0)
                {
                    if (contr != 0)
                    {
                        contr--;
                    }
                    contg++;
                    while (contb < 255 && contr == 0)
                    {
                        if (contg != 0)
                        {
                            contg--;
                        }
                        contb++;
                    }
                }
            }
            custom = Color.FromArgb(contr, contg, contb);
            this.BackColor = custom;
    } while (true);
}

【问题讨论】:

  • 它可以工作,但可能变化太快。
  • 当我运行它时它只显示为半透明

标签: c# forms winforms colors


【解决方案1】:

非常简单,您没有延迟。由于这个Link添加

Thread.Sleep(1000);

所有这些都必须在单独的线程上发生! 否则你的用户界面会卡住

Check This

【讨论】:

    【解决方案2】:

    首先,您当前的代码不起作用,但不是因为任何线程问题(尽管确实需要解决)。

    问题是这些行永远不会被击中:

    custom = Color.FromArgb(contr, contg, contb);
    this.BackColor = custom;
    

    while 循环中的逻辑不起作用。

    你产生的值是一组:

    (0, 0, 1), (0, 0, 2) ... (0, 0, 255), (0, 254, 1), (0, 253, 2) ... (0, 1, 254)
    

    然后它只是重复尝试产生这些值,但永远无法摆脱while (contr &lt; 255 &amp;&amp; contg == 0) 循环。

    现在,假设这实际上是您想要的,那么我建议最好的方法是使用 Microsoft 的响应式框架。只需 NugGet "Rx-WinForms" 然后您就可以编写以下代码:

    var ranges = new[]
    {
        Observable.Range(1, 255).Select(x => Color.FromArgb(0, 0, x)),
        Observable.Range(1, 254).Select(x => Color.FromArgb(0, 255 - x, x)),
    };
    
    var query =
        ranges
            .Concat()
            .Zip(Observable.Interval(TimeSpan.FromMilliseconds(100.0)), (x, i) => x)
            .Repeat()
            .ObserveOn(this);
    
    var subscription = query.Subscribe(c => this.BackColor = c);
    

    所以rangesIObservable&lt;Color&gt; 的数组。在 ranges 上调用 .Concat() 会将其从 IObservable&lt;Color&gt;[] 变为 IObservable&lt;Color&gt;.Zip 将每个值与一个以 10 毫秒为增量的计时器关联起来(如果您愿意,可以更改该值)。调用.Repeat() 只是不断重复循环——有点像while (true)。然后.ObserveOn(this) 强制可观察订阅在 UI 线程上运行。

    最后,.Subscribe(...) 实际运行 observable 并更新表单的 BackColor

    这样做的好处是您可以随时通过在订阅上调用.Dispose() 来停止订阅:

    subscription.Dispose();
    

    这会清理所有线程和计时器。这是一个非常巧妙的解决方案。

    【讨论】:

      猜你喜欢
      • 2015-06-19
      • 2015-12-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多