2015-05-25 15 views
6

Desidero che il mio programma cambi costantemente il colore di sfondo del font, ma voglio che vada liscio, quindi ho provato a modificare una variabile di colore ma non lo uso per il colore di sfondo del modulo this.BackColor = custom; funziona e non so come farlo funzionare, ecco il codice completo:Cambia colore modulo costantemente

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

Funzionerebbe, ma probabilmente cambiando troppo velocemente. – Shaharyar

+0

quando lo eseguo è solo in versione semi trasparente –

+0

Questa finestra è configurata? – Enigmativity

risposta

1

Per cominciare, il codice corrente non funziona, ma non a causa di alcun problema di threading (anche se questo ha bisogno di essere risolto).

Il problema è che queste righe non vengono colpiti:

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

La logica nei while loop semplicemente non funzionano.

I valori che si producono sono l'insieme di:

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

E poi basta ripetere tentativi per produrre tali valori, ma non possono mai uscire dal giro while (contr < 255 && contg == 0).

Ora, supponendo che sia in realtà ciò che volevi, suggerisco che l'approccio migliore per farlo è utilizzare il Reactive Framework di Microsoft. A soli Nugget "RX-WinForms" e quindi è possibile scrivere questo codice:

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

Così ranges è un array di IObservable<Color>. Chiamando .Concat() su ranges si trasforma da IObservable<Color>[] a IObservable<Color>. Lo .Zip lega ogni valore a un conteggio del tempo con incrementi di 10 ms (è possibile modificare il valore se lo si desidera). Chiamando .Repeat() si ripete continuamente il ciclo, una specie di come while (true). Quindi .ObserveOn(this) impone l'esecuzione della sottoscrizione osservabile sul thread dell'interfaccia utente.

Infine, lo .Subscribe(...) esegue effettivamente l'osservabile e aggiorna lo BackColor del modulo.

La cosa bella di questo è che si può fermare l'abbonamento in qualsiasi momento chiamando .Dispose() sulla sottoscrizione:

subscription.Dispose(); 

che pulisce tutti i thread e il timer. È una soluzione molto accurata.

5

molto semplice non si ha ritardo. a causa di questo Link aggiungere

Thread.Sleep(1000); 

tutto questo deve accadere in un thread separato! o l'interfaccia utente sarà bloccato

Check This

+1

Grazie, ha funzionato bene –

+0

@Fernando Belous benvenuto allo stackoverflow se una risposta ti ha aiutato a non dover commentare, contrassegnala come risposta corretta in modo che gli altri sappiano che è stato lui a risolvere il tuo problema. e prego! – Nahum