6


0

C#でWindowsフォームのテキストボックスを更新するときに「フラッシュ」効果をプログラムするにはどうすればよいですか?

私が持っているのは、7つのテキストボックスがあるC#のWindowsフォームです。 各テキストボックスは、値が変更されて受け入れられると、2つまたは3つの他のテキストボックスを更新します。 私がやりたいのは、何らかの形で更新する必要があるテキストボックスを取得し、明るいバックカラーなどで「フラッシュ」することです。 目的は、ユーザーに更新されている内容を少しだけ追加して見せることです。

これを行う簡単な方法があるかどうかはわかりません。そのため、ここで質問しています。 タイマー、whileループ、およびテキストボックスのアルファチャネルが減少するバックカラーを使用してバックカラーを制御できると思いますが、より良い方法があるかどうかを確認したいと思います。

jQuery UIには、達成したいことを示す「ハイライト」効果があります(ただし、少し遅くしたいです)。 jQuery UIエフェクトデモページにアクセスし、ウィンドウのドロップダウンボックスから[ハイライト]を選択して、[エフェクトの実行]をクリックします。

編集 +時間とリソースの制約に基づいて独自のソリューションを使用する必要がありましたが、Hans Passantが述べたように、テキストボックスは透明色をサポートしていません。 そこで、コントロールが完全に白になるまでR、G、およびBの値を増やす自己停止タイマーを使用しました(R = 255、G = 255、B = 255)。

  • Edit 2 * + .NET 4.0に更新した後、George Johnstonのソリューションのバリエーションを使用して、拡張メソッドとしてflashイベントを再コーディングしました。 これは非常にクリーンなソリューションであり、拡張メソッドにより、「使用」するすべてのユーザーが自動的に使用できるようになります。

6 Answer


11


テキストボックスの点滅中にフォームの使用をブロックしないように、点滅するテキストボックスごとに個別のスレッドをスピンオフできます。 スレッドの回転にはクロススレッドが必要になるため、必ずフォームを呼び出してください。 以下の完全なソリューション。

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

これにより、サポートするタイマーコントロールをフォームに配置する必要がなくなります。


3


WPFはこれに最適です。 WPFで作成し、WinFormsでHostedElementとして使用できます。 新しいプロジェクトWPFユーザーコントロールを追加し、これをxamlに追加します。


(少し作業を行うこともできますが、開始点です)。 そこにあなたはそれを持っています-派手なテキストボックス:)

ソリューションをビルドすると、新しいアイテムがツールボックスに表示されます。フォームにドラッグアンドドロップするだけで、WPFはElementHost要素内でホストされます。 WPFの優れた点は、WPFのビジュアルスタイルではるかに多くのことができることですが、WPFがホストされているため、ソリューションに一定の重みが追加されます。


2


`TextBox`から独自のクラスを派生させます。 フラッシュを開始する `Flash()`メソッドを指定します。 「BackColor」をパステルカラーに変更するだけです。 アルファを使用しないでください。アルファは「TextBox」では機能しません。

同時にフラッシュするように、このクラスのすべてのインスタンスに共通のタイマーを共有させる必要があります。 タイマーを静的にし、所有しているインスタンスの数を参照カウントします。 コンストラクタに追加し、 `Dispose(bool)`オーバーライドに追加します。


0


WinFormsの使用方法を設定している場合は、知識が限られていますが、サードパーティのコントロールを手伝ってもらうことをお勧めします。 名前をいくつか挙げると、TelerikとComponentOneです。 WinFormsのようなものが必要な場合は、おそらくWPFを利用して、XAMLでカスタムアニメーションを開発できます(UI状態とアニメーションの作成ではSilverlight XAMLと似ていると思います)。 これら以外に、私は助けを提供するために経験不足です。


0


アプリに応じて、これを行うための1つの派手な方法は、テキストボックスの画像のガンマを変更することです。 これはもちろん、どれだけの時間をこれに費やしたいかによって異なりますが、確かに実行可能です。 画像のガンマを調整する方法に関するいくつかのチュートリアルを見てきましたが、コントロールの画像を取得するのは簡単です。

そうは言っても、テキストボックスの背景色を透明に設定することは簡単ではないと思います。 あなたの言葉遣いから、基になるコントロールの背景色からテキストボックスの背景色に色をフェードしたいだけだと推測できます。その場合、問題は再び些細です。 しかし、あなたが持っている場合、すなわち 背景画像の場合、おそらく再考する必要があります。 それにもかかわらず、それはまだ可能であり、あなたがそれを達成しようとしているのであれば、これを行う方法に関するリンクを掘り下げることができます。

すばやく簡単な解決策は、テキストの色と背景の色を白から現在の前景色にアニメーション化することです。


0


スレッドの使用に興味がない場合は、ここでジョージジョンストンの答えに基づいて、私の実装は次のようになります。

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