簡體   English   中英

使用C#更新Windows窗體中的文本框時,如何編寫“閃存”效果?

[英]How do I program a “flash” effect when updating text boxes in a windows form with C#?

我所擁有的是一個Windows窗體,在C#中,有7個文本框。 當其值被更改和接受時,每個文本框都會更新2或3個其他文本框。 我想要做的是以某種方式采取那些需要更新的文本框,並使用淺色或其他東西使它們“閃爍”。 目的是向用戶顯示正在更新的內容,增加了一點天賦。

我不確定是否有一種簡單的方法可以做到這一點,這就是我在這里問的原因。 我可以使用計時器,while循環和背面顏色,文本框上的alpha通道遞減控制背面顏色,我想,但我想看看是否有更好的方法。

jQuery UI有一個“突出顯示”效果,顯示我想要完成的任務(雖然我希望我的速度有點慢)。 只需轉到jQuery UI Effects Demo頁面 ,從窗口的下拉框中選擇“highlight”,然后單擊“Run Effect”。

編輯
我不得不根據時間和資源限制使用自己的解決方案,但文本框不支持Hans Passant提到的透明色。 所以,我使用了一個自動停止計時器來增加R,G和B值,直到控制器完全變白(R = 255,G = 255,B = 255);

編輯2
在我們更新到.NET 4.0之后,使用George Johnston解決方案的變體,將Flash事件重新編碼為擴展方法。 我覺得這是一個更清潔的解決方案,擴展方法使任何using它的人都可以自動using它。

您可以為每個閃爍的文本框分離一個單獨的線程,以免在您的文本框閃爍期間阻止您的表單被使用。 一定要調用您的表單,因為線程的旋轉將需要交叉線程。 完整解決方案如下

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

這樣可以避免在表單上放置支持計時器控件。

WPF對此似乎是完美的。 您可以在WPF中構建它並在WinForms中將其用作HostedElement。 添加新項目WPF用戶控件,這在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>

(它可以做一點工作,但這是一個開始)。 你有它 - 一個花哨的文本框:)

構建解決方案,新項目將出現在工具箱中 - 只需拖放到您的表單,WPF將托管在ElementHost元素中。 它的美妙之處在於你可以在WPF中以視覺風格做更多的事情,但是,它托管的WPF為你的解決方案增加了一定的重量......

TextBox派生自己的類。 給它一個Flash()方法來啟動閃爍。 只需將BackColor更改為柔和的顏色即可。 不要使用不適用於TextBox alpha。

你應該讓這個類的所有實例共享一個共同的Timer,這樣它們就會同時閃爍。 使計時器靜態並引用計數您擁有的實例數。 在構造函數中添加,在Dispose(bool)覆蓋中向下。

如果你對使用線程不感興趣,建立在George Johnston的答案上,我的實現如下:

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

如果你已經開始使用WinForms,那么憑借我有限的知識,我可以建議讓第三方控件來幫忙。 一些名稱是Telerik和ComponentOne。 如果你想要WinForms之類的東西,你可以使用WPF,並在XAML中開發自定義動畫(我認為在創建UI狀態和動畫時類似於Silverlight XAML)。 除了這些,我沒有經驗提供任何幫助。

根據您的應用程序,一種華而不實的方法是更改​​文本框圖像的灰度系數。 這當然取決於你想要投入多少時間,但這肯定是可行的。 我已經看過幾個關於如何調整圖像的灰度系數的教程,並且獲得控件的圖像是微不足道的。

也就是說,我也相信將文本框的背景顏色設置為透明是非常重要的。 根據你的措辭,我只能猜測你想要將底層控件的背景顏色淡化到文本框的背景顏色,在這種情況下問題再次微不足道。 但是,如果你有背景圖像,你應該重新考慮。 盡管如此,它仍然是可能的,如果這是你想要完成的,我可以為你找到如何做到這一點的鏈接。

快速簡單的解決方案是將文本顏色和背景顏色從白色設置為當前前景色。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM