2010-11-10 13 views
6

Quello che ho è un modulo di Windows, in C#, con 7 caselle di testo. Ogni casella di testo aggiorna 2 o 3 altre quando il suo valore è cambiato e accettato. Quello che voglio fare è in qualche modo prendere quelle caselle di testo che devono essere aggiornate e renderle "flash" con un retroilluminazione o qualcosa del genere. Lo scopo è mostrare all'utente ciò che viene aggiornato con un tocco in più.Come si programma un effetto "flash" quando si aggiornano le caselle di testo in un modulo di Windows con C#?

io non sono sicuro se c'è un modo semplice per fare questo ed è per questo che sto chiedendo qui. Posso usare un timer, un ciclo while e un colore posteriore con un canale alfa decrescente sul control back color, credo, ma voglio vedere se c'è un modo migliore.

jQuery UI ha un effetto "Evidenzia" che mostra ciò che voglio realizzare (anche se io voglio la mia per essere un po 'più lento). Vai qui allo jQuery UI Effects Demo page, seleziona "evidenzia" dalla casella a discesa nella finestra e fai clic su "Esegui effetto".

Modifica
ho dovuto andare con la mia propria soluzione basata su mio tempo e di risorse vincoli, ma le caselle di testo non supportano colori trasparenti come detto da Hans Passant. Quindi, ho usato un timer auto-stop che aumenta i valori R, G e B fino a quando il controllo è completamente bianco (R = 255, G = 255, B = 255);

Edit 2
ferita fino ricodifica l'evento Flash come un metodo di estensione utilizzando una variante della soluzione di George Johnston dopo abbiamo aggiornato a .NET 4.0. Questa è una soluzione molto più pulita, credo, e il metodo di estensione lo rende automaticamente disponibile a chiunque using.

+0

Penso che il vostro metodo è la soluzione dritto in avanti. La semplice di JQuery è per la pagina Web ... – Bolu

+1

Vero. Lo scopo del collegamento jQuery è di dare un esempio visivo di ciò che voglio realizzare. –

+0

In base al vincolo sul tempo e ad altre limitazioni, suppongo che se la mia idea è OK, devo andare con quella. È di gran lunga il più semplice e facile/veloce da codificare con la mia esperienza e le risorse disponibili. Tutte queste sono grandi risposte e apprezzo l'input. Ho aggiornato la mia domanda con il nuovo metodo che sto usando. –

risposta

9

Si potrebbe girare un filo separato per casella di testo lampeggiante come per non blocca il tuo modulo dall'essere utilizzato durante il flashing delle tue textbox. Assicurati di invocare il tuo modulo come filatura del thread richiederà cross threading. Soluzione completa di seguito.

private void Form1_Load(object sender, EventArgs e) 
{ 
    // textBox1 is the control on your form. 
    // 1000 is the total interval between flashes 
    // Color.LightBlue is the flash color 
    // 10 is the number of flashes before the thread quits. 
    Flash(textBox1, 1000,Color.LightBlue,10); 
    Flash(textBox2, 1500,Color.Green,10); 
    Flash(textBox3, 100,Color.Red,10); 
    Flash(textBox4, 500,Color.Brown,10); 
    Flash(textBox5, 200,Color.Pink,10); 
} 

public void Flash(TextBox textBox, int interval, Color color, int flashes) 
{ 
    new Thread(() => FlashInternal(textBox, interval, color, flashes)).Start(); 
} 

private delegate void UpdateTextboxDelegate(TextBox textBox, Color originalColor); 
public void UpdateTextbox(TextBox textBox, Color color) 
{ 
    if (textBox.InvokeRequired) 
    { 
     this.Invoke(new UpdateTextboxDelegate(UpdateTextbox), new object[] { textBox, color }); 
    } 
    textBox.BackColor = color; 
} 

private void FlashInternal(TextBox textBox, int interval, Color flashColor, int flashes) 
{ 
    Color original = textBox.BackColor; 
    for (int i = 0; i < flashes; i++) 
    { 

     UpdateTextbox(textBox, flashColor); 
     Thread.Sleep(interval/2); 
     UpdateTextbox(textBox, original); 
     Thread.Sleep(interval/2); 
    } 
} 

Ciò evita di dover inserire i controlli del timer di supporto nel modulo.

+0

Wow. Questa è una buona idea, anche se ho bisogno del capo per andare avanti da .NET 2.0. A partire da ora questo è il framework a cui puntiamo e non abbiamo il supporto per le espressioni Lambda. Inoltre, non penso di poter ottenere questo codice e di lavorare con il progetto in tempo. Il tuo aiuto è apprezzato, però. –

+0

Siamo passati a .NET 4 un po 'di tempo fa, quindi ho finito per ricodificare l'evento flash e utilizzare una variante della soluzione. Utilizzato un metodo di estensione in modo da poter chiamare 'myTextBox.Flash (...)'. :) Grazie per il suggerimento. –

0

Se si sono impostati sui vostri modi in utilizzando WinForms, poi con la mia limitata conoscenza, posso suggerire ottenere caso di comando per dare una mano. Alcuni da nominare sono Telerik e ComponentOne. Se vuoi qualcosa di simile a WinForms, puoi probabilmente utilizzare WPF e sviluppare animazioni personalizzate in XAML (che penso siano simili a Silverlight XAML nella creazione di stati dell'interfaccia utente e animazioni). Oltre a questi, non ho esperienza per fornire alcun aiuto.

+1

Non mi sembra un motivo poco convincente per ipotizzare le potenziali difficoltà di una libreria di controllo di terze parti quando è possibile ottenere l'effetto che si cerca qui semplicemente in un controllo derivato. Sarebbe interessante sapere se eventuali controlli di terze parti implementano questa funzionalità in modo diverso rispetto a quanto suggerito dalla domanda. –

0

A seconda della tua app, un modo appariscente per farlo è cambiando la gamma di un'immagine della tua casella di testo. Questo ovviamente dipende da quanto tempo si vuole mettere in questo, ma è certamente fattibile. Ho visto diversi tutorial su come regolare la gamma di un'immagine e ottenere un'immagine del tuo controllo è banale.

Detto questo, credo anche che sia banale per impostare il colore di sfondo della casella di testo a trasparente. Dalla tua formulazione posso solo indovinare che vuoi sbiadire il colore dal backcolor del controllo sottostante al backcolor della textbox, nel qual caso il problema è di nuovo banale. Ma se hai un'immagine di sfondo, dovresti forse riconsiderarla. Tuttavia, è ancora possibile e posso trovare un link per te su come farlo se è quello che stai cercando di realizzare.

La soluzione rapida e semplice sarebbe quella di animare il colore del testo e il colore del retro dal bianco al colore di primo piano corrente.

3

Il WPF sembrerebbe perfetto per questo. Puoi crearlo in WPF e usarlo in WinForms come HostedElement. Aggiungi nuovo progetto WPF di controllo utente, e questo in XAML:

<UserControl x:Class="WpfControlLibrary1.UserControl1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="20" d:DesignWidth="300"> 
<TextBox> 
    <TextBox.Triggers> 
     <EventTrigger RoutedEvent="TextBox.TextChanged"> 
      <BeginStoryboard> 
       <Storyboard AutoReverse="False" BeginTime="0" > 
        <DoubleAnimation Storyboard.TargetName="Foo" 
           Storyboard.TargetProperty="Opacity" 
           From="0" To="1" Duration="0:0:1"/> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </TextBox.Triggers> 
    <TextBox.Background> 
     <SolidColorBrush Opacity="1" x:Name="Foo" Color="LightGray" /> 
    </TextBox.Background> 
</TextBox> 
</UserControl> 

(si potrebbe fare un po 'di lavoro, ma è un inizio).Ecco qui: una fantasiosa casella di testo :)

Costruisci la soluzione e un nuovo elemento apparirà nella casella degli strumenti - trascina il modulo & nel modulo, il WPF sarà ospitato all'interno dell'elemento ElementHost. La bellezza di ciò è che puoi fare molto di più negli stili visivi in ​​WPF, tuttavia, è ospitato WPF che aggiunge un certo peso alla tua soluzione ...

+1

Non ho mai lavorato con WPF prima. Questo è davvero bello. Anche se, con una mancanza di tempo per imparare in questo momento e un progetto che non è convertito in .NET 4.0 (dobbiamo aspettare l'approvazione del capo prima della conversione) devo andare con una risposta diversa. Controllerò in WPF, comunque. –

2

Ottieni la tua classe da TextBox. Dargli un metodo Flash() che inizia a lampeggiare. Basta cambiare il BackColor in un colore pastello. Non utilizzare alpha, che non funziona su un TextBox.

È necessario che tutte le istanze di questa classe condividano un timer comune in modo che lampeggino allo stesso tempo. Rendi il timer statico e di riferimento: conta il numero di istanze che hai. Sommare nel costruttore, in basso nella sostituzione di Dispose(bool).

+0

Questa è una grande idea e potrei implementarla più tardi. Ho preso in considerazione l'idea di creare una mia casella di testo derivata per la formattazione e la convalida speciali, quindi questo potrebbe rientrare nell'ambito di tale progetto. –

0

Se non siete interessati ad utilizzare threading, sulla risposta di George Johnston qui il mio implementazione è la seguente:

private bool CurrentlyFlashing = false; 
private void FlashInternal(TextBox textBox, int interval, Color flashColor, int flashes) 
{ 
    if (CurrentlyFlashing) return; 

    CurrentlyFlashing = true; 
    Color original = textBox.BackColor; 
    for (int i = 0; i < flashes; i++) 
    { 
     UpdateTextbox(textBox, flashColor); 
     Application.DoEvents(); 
     Thread.Sleep(interval/2); 
     UpdateTextbox(textBox, original); 
     Application.DoEvents(); 
     Thread.Sleep(interval/2); 
    } 
    CurrentlyFlashing = false; 
} 
private delegate void UpdateTextboxDelegate(TextBox textBox, Color originalColor); 
public void UpdateTextbox(TextBox textBox, Color color) 
{ 
    if (textBox.InvokeRequired) 
    { 
     this.Invoke(new UpdateTextboxDelegate(UpdateTextbox), new object[] { textBox, color }); 
    } 
    textBox.BackColor = color; 
} 
Problemi correlati