Wie programmiere ich ein „Flash“ -Effekt, wenn Textfelder in einem Windows-Aktualisierung mit C # bilden?

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

Frage

Was ich habe, ist ein Windows-Formular, in C #, mit 7 Textfeldern ein. Jedes Textfeld aktualisiert 2 oder 3 andere, wenn ihr Wert geändert und akzeptiert wird. Was ich tun möchte, ist irgendwie diese Textfelder nehmen, dass Bedarf aktualisiert werden und sie „flash“ mit einem leichten Hintergrundfarbe oder etwas zu machen. Der Zweck ist, den Benutzer zu zeigen, was mit einem zusätzlichen Bit Flair aktualisiert wird.

Ich bin nicht sicher, ob es eine einfache Möglichkeit, dies zu tun, und das ist, warum ich hier bin gefragt. Ich kann einen Timer verwenden, eine while-Schleife, und eine Hintergrundfarbe mit einem Alpha-Kanal auf der Textfeld-Steuerelement zurück Farbe abnehmen, denke ich, aber ich mag sehen, ob es ein besserer Weg ist.

jQuery UI hat einen „Highlights“ Effekt das zeigt, was ich erreichen will (obwohl ich mein will etwas langsamer sein). Gehen Sie einfach hier, um den jQuery UI-Effekte Demo-Seite , wählen Sie „Highlights“ aus dem Dropdown-Feld in das Fenster, und klicken Sie auf "Run-Effekt".

Bearbeiten
Ich hatte mit meiner eigenen Lösung auf Basis von meiner Zeit und Ressourcenbeschränkungen zu gehen, aber Textfelder unterstützen keine transparenten Farben wie von Hans Passant erwähnt. Also habe ich eine Selbstanhaltezeitgeber, erhöht sich die R-, G- und B-Werte, bis die Steuerung vollständig weiß ist (R = 255, G = 255, B = 255);

Bearbeiten 2
Liquidiert Umkodierung des Blitzereignisses als Erweiterung Methode eine Variation von George Johnston-Lösung verwenden, nachdem wir zu .NET 4.0 aktualisiert. Dies ist eine viel sauberere Lösung, ich fühle mich, und die Extension-Methode macht es jedem using es automatisch zur Verfügung.

War es hilfreich?

Lösung

Sie könnten einen separaten Thread ausgliedern Textbox, um nicht zu blockieren Ihre Form von pro blinkt während der Blink Ihrer Textbox (e) verwendet werden. Seien Sie sicher, dass Ihre Form wie Spinnen des Fadens berufen wird Gewinde erforderlich. Vollständige Lösung unten.

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

Dadurch wird die Unterstützung Timer Kontrollen auf dem Formular zu setzen haben.

Andere Tipps

Die WPF würde für diese perfekt zu sein scheinen. Sie können es in WPF erstellen und verwenden es in WinForms als HostedElement. Hinzufügen neues Projekt WPF User Control und dieses 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>

(es könnte ein wenig Arbeit tun, aber es ist ein Anfang). Da haben Sie es - ein schickes Textbox:)

Erstellen Sie die Lösung und ein neues Element wird in Toolbox angezeigt - einfach per Drag & Drop in das Formular, wird die WPF innerhalb Elements Elements gehostet werden. Das Schöne daran ist, dass man viel, viel mehr in visuelle Stile in WPF zu tun, aber WPF es gehostet, die zu Ihrer Lösung bestimmtes Gewicht hinzufügt ...

Man leitet eine eigene Klasse von TextBox. Geben Sie ihm eine Flash() Methode, die das Blinken beginnt. Ändern Sie einfach die BackColor zu Pastellfarben. Verwenden Sie keine alpha, das nicht funktioniert auf einem TextBox.

Sie sollten alle Instanzen dieser Klasse eine gemeinsame Timer haben, so dass sie in der gleichen Zeit zu blinken. Machen Sie den Timer statische und Referenz zählen die Anzahl der Instanzen, die Sie haben. Fügen Sie bis in den Konstruktor, unten im Dispose(bool) außer Kraft setzen.

Wenn Sie WinForms auf dem Weg verwendet, dann mit meiner begrenzten Kenntnis gesetzt sind, kann ich vorschlagen Dritte Kontrollen immer zu helfen. Ein paar zu nennen sind Telerik und ComponentOne. Wenn Sie etwas WinForms wollen mögen, können Sie wahrscheinlich WPF nutzen und benutzerdefinierte Animationen in XAML entwickeln (was meiner Meinung nach Silverlight XAML ähnlich ist bei der Schaffung von UI-Staaten und Animationen). Anders als diese, ich bin Erfahrung heraus jede Hilfe zur Verfügung zu stellen.

Je nach Anwendung, eine auffällige Art und Weise, dies zu tun ist durch die Gamma eines Bild Ihrer Textbox ändern. Dies hängt natürlich davon ab, wie viel Zeit Sie in diese setzen, aber es ist sicherlich machbar. Ich habe einige Tutorials zu sehen, wie die Gamma eines Bildes anpassen und ein Bild Ihrer Kontrolle zu bekommen ist trivial.

sagte, dass, ich glaube auch, es ist nicht trivial, die Hintergrundfarbe der Textbox zu transparent setzen. Aus Ihrer Benennung kann ich denke, Sie wollen nur die Farbe aus der zugrunde liegenden Kontrolle des Hintergrundfarbe in das Textfeld‘Hintergrundfarbe verblassen, wobei in diesem Fall das Problem trivial wieder an ist. Aber wenn Sie das heißt ein Hintergrundbild haben, sollten Sie vielleicht überdenken. Dennoch ist es immer noch möglich, und ich kann einen Link für Sie, wie Sie dies tun, graben, wenn das, was Sie erreichen wollen.

Die Quick'n einfache Lösung wäre es, die Textfarbe und die Hintergrundfarbe von weiß auf Ihrem aktuellen Vordergrundfarbe zu animieren.

Wenn Sie bei der Verwendung Threading nicht interessiert sind, aufbauend auf George Johnston Antwort hier meine Implementierung ist wie folgt:

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

Pretty alte Frage, aber ich dachte, dass ich mit einer moderneren Antwort aktualisieren würde, da async / await gab es im Jahr 2010 nicht, als die letzten Antworten beantworteten

ich die Aktualisierung auch eine schön Verblassen Single-Flash-Verwendungen eher als ein Anfall auslösende Ein-Aus-Blinken, und und die Eingabe so geändert, dass es nicht auf Textfelder verwendet werden, beschränkt ist.

Da es nutzt async / await, es ist sicher auf dem Haupt-Thread zu tun, ohne die Delegaten zu benötigen oder die InvokeRequired überprüfen. Selbst wenn Sie die Dauer der Einblendung auf etwas lang eingestellt, werden Sie noch in der Lage sein, mit der Anwendung zu interagieren, während die Fade-Schleife läuft.

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

ich hartcodiert die Farbe und das Timing, anstatt sie als Funktionsparameter ausgesetzt wird, wie andere Antworter tat, weil ich möchte, dass sie im Allgemeinen die gleiche über meine Anwendung sein, wenn ich diese wiederverwendet werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top