Fernando Belous
Fernando Belous

Reputation: 63

Change Form color constantly

I want my program to constantly change the font background color, but I want it to go smoothly so I tried to modify a Color variable Color custom; and use it to for the background color of the form this.BackColor = custom; but it doesn't work and I don't know how to make it work, here is the complete code:

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

Upvotes: 6

Views: 1269

Answers (2)

Enigmativity
Enigmativity

Reputation: 117019

To start with, your current code doesn't work, but not because of any threading issue (although that does need to be solved).

The issue is that these lines never get hit:

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

The logic in your while loops just don't work.

The values that you produce are the set of:

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

It then just repeated tries to produce those values, but can never break out of the while (contr < 255 && contg == 0) loop.

Now, assuming that's actually what you wanted then I suggest the best approach to do this is using Microsoft's Reactive Framework. Just NugGet "Rx-WinForms" and you can then write this code:

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);

So ranges is an array of IObservable<Color>. Calling .Concat() on ranges turns it from IObservable<Color>[] to IObservable<Color>. The .Zip ties each value to a timer counting off in 10ms increments (you can change the value if you wish). Calling .Repeat() just repeats the loop continuously - sort of like while (true). Then .ObserveOn(this) forces the observable subscription to be run on the UI thread.

Finally, the .Subscribe(...) actually runs the observable and updates the BackColor of the form.

The nice thing about this is that you can stop the subscription at any time by calling .Dispose() on the subscription:

subscription.Dispose();

That cleans up all of the threads and the timer. It's a very neat solution.

Upvotes: 1

Nahum
Nahum

Reputation: 7197

very simple you have no delay. due to this Link add

Thread.Sleep(1000);

all this HAS to happen on a separate thread! or your UI will be stuck

Check This

Upvotes: 5

Related Questions