Come faccio a programmare un effetto “flash” durante l'aggiornamento caselle di testo in un Windows Form con C #?

StackOverflow https://stackoverflow.com/questions/4147169

Domanda

Quello che ho è una forma di Windows, in C #, con 7 caselle di testo. Ogni casella di testo aggiorna 2 o 3 altri quando il suo valore è cambiato e accettato. Quello che voglio fare è in qualche modo prendere le caselle di testo che devono essere aggiornati e "flash" con una parte posteriore di colore chiaro o qualcosa fare. Lo scopo è quello di mostrare all'utente ciò che viene aggiornato con un po 'aggiunto di fascino.

Non sono sicuro se c'è un modo semplice per fare questo ed è per questo che sto chiedendo qui. Posso utilizzare un timer, un ciclo while, e un colore di nuovo con una diminuzione canale alfa del colore di controllo posteriore casella di testo, 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). Basta andare qui per il jQuery UI Effetti Demo pagina , selezionare "highlight" dalla casella a discesa nella la finestra, e fare clic su "effetto Run".

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. Così, ho usato un timer di auto-arresto che aumenta la R, G, B e valori finché il controllo è completamente bianco (R = 255, G = 255, B = 255);

Modifica 2
Liquidazione ricodifica l'evento Flash come un metodo di estensione utilizzando una variante della soluzione di George Johnston dopo abbiamo aggiornato a .NET 4.0. Si tratta di una soluzione più pulita molto, mi sento, e il metodo di estensione rende automaticamente a disposizione di chiunque using esso.

È stato utile?

Soluzione

Si potrebbe spin-off un thread separato per lampeggiante testo da non bloccare il modulo venga utilizzato durante il lampeggio del testo (s). Assicurarsi di richiamare la vostra forma come la filatura del filo richiederà threading croce. 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);
    }
}

Questo evita di dover mettere sostenere controlli timer sul modulo.

Altri suggerimenti

Il WPF sembrerebbe perfetto per questo. È possibile costruire in WPF e utilizzarlo in WinForms come HostedElement. Aggiungere un 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). Là lo avete - una casella di testo di fantasia:)

Generare la soluzione, e un nuovo elemento verrà visualizzato nella Toolbox - solo drag & drop al modulo, il WPF sarà ospitato all'interno dell'elemento ElementHost. Il bello è che si può fare molto altro ancora a stili di visualizzazione in WPF, tuttavia, è ospitato WPF che aggiunge certo peso alla soluzione ...

Derive la propria classe da TextBox. Dategli un metodo Flash() che avvia il lampeggio. Basta cambiare il BackColor ad un colore pastello. Non utilizzare alfa, che non funziona su un TextBox.

Si dovrebbe avere tutte le istanze di questa classe condividono un timer comune, in modo che lampeggiano allo stesso tempo. Fare la statica timer e di riferimento-contare il numero di istanze che avete. Sommate nel costruttore, giù in sostituzione Dispose(bool).

Se si è impostato sui vostri modi in utilizzando WinForms, poi con la mia conoscenza limitata, posso suggerire ottenere controlli di terze parti per dare una mano. Alcuni di nome sono Telerik e ComponentOne. Se volete qualcosa di WinForms piace, probabilmente si può utilizzare WPF, e sviluppare le animazioni personalizzate in XAML (che secondo me sono simili a Silverlight XAML nella creazione di stati di interfaccia utente e animazioni). Oltre a queste, sono fuori di esperienza per fornire qualsiasi aiuto.

A seconda della vostra applicazione, in un modo appariscente di fare questo è cambiando la gamma di un'immagine della vostra casella di testo. Questo naturalmente dipende da quanto tempo si desidera mettere in questo, ma è certamente fattibile. Ho visto diversi tutorial su come regolare la gamma di un'immagine e ottenere un'immagine del vostro controllo è banale.

Detto questo, credo anche che sia banale per impostare il colore di sfondo della casella di testo a trasparente. Dal tuo testo Posso solo immaginare che si desidera a sbiadire il colore dal backcolor del controllo sottostante al backcolor testo', nel qual caso il problema è ancora una volta banale. Ma se si dispone di un'immagine vale a dire uno sfondo, si dovrebbe forse riconsiderare. Tuttavia, è ancora possibile e posso scavare un link per voi su come fare questo, se è questo che stai cercando di realizzare.

La soluzione facile Quick'n sarebbe quella di animare il colore del testo e il colore di nuovo dal bianco al colore di primo piano corrente.

Se non sei interessato 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;
}

Piuttosto vecchia questione, ma ho pensato di aggiornare con una risposta più moderna, dal momento che asincrona / await non esistevano nel 2010, quando ha risposto alle ultime risposte

Ho anche aggiornandolo ad usi un ben dissolvenza-flash piuttosto che un sequestro induce on-off lampeggio, ed e cambiato la digitazione in modo che non si limita ad essere utilizzato su caselle di testo.

Dal momento che utilizza async / attendono, è sicuro di fare sul thread principale senza bisogno il delegato o l'assegno InvokeRequired. Anche se si imposta la durata della dissolvenza a qualcosa di lungo, sarà comunque in grado di interagire con l'applicazione mentre il ciclo di dissolvenza è in esecuzione.

    private bool CurrentlyFlashing = false;
    private async void FlashControl(Control control)
    {
        Color flashColor = Color.Yellow;

        float duration = 500; // milliseconds
        int steps = 10;
        float interval = duration / steps;

        if (CurrentlyFlashing) return;
        CurrentlyFlashing = true;
        Color original = control.BackColor;

        float interpolant = 0.0f;
        while (interpolant < 1.0f)
        {
            Color c = InterpolateColour(flashColor, original, interpolant);
            control.BackColor = c;
            await Task.Delay((int) interval);
            interpolant += (1.0f / steps);
        }

        control.BackColor = original;

        CurrentlyFlashing = false;
    }

    public static Color InterpolateColour(Color c1, Color c2, float alpha)
    {
        float oneMinusAlpha = 1.0f - alpha;
        float a = oneMinusAlpha * (float)c1.A + alpha * (float)c2.A;
        float r = oneMinusAlpha * (float)c1.R + alpha * (float)c2.R;
        float g = oneMinusAlpha * (float)c1.G + alpha * (float)c2.G;
        float b = oneMinusAlpha * (float)c1.B + alpha * (float)c2.B;
        return Color.FromArgb((int)a, (int)r, (int)g, (int)b);
    }

I hard-coded il colore e la tempistica piuttosto che esporli come parametri di funzione come altre answerers fatto, dal momento che in genere voglio che siano la stessa in tutta la mia domanda se riutilizzare questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top