使用C#更新Windows窗体中的文本框时,如何编写“闪存”效果?

我所拥有的是一个Windows窗体,在C#中,有7个文本框。 当其值被更改和接受时,每个文本框都会更新2或3个其他文本框。 我想要做的是以某种方式采取那些需要更新的文本框,并使用浅色或其他东西使它们“闪烁”。 目的是向用户显示正在更新的内容,增加了一点天赋。

我不确定是否有一种简单的方法可以做到这一点,这就是我在这里问的原因。 我可以使用计时器,while循环和背面颜色,文本框上的alpha通道减少控制背面颜色,我想,但我想看看是否有更好的方法。

jQuery UI有一个“突出显示”效果,显示我想要完成的任务(虽然我希望我的速度有点慢)。 只需转到jQuery UI Effects演示页面 ,从窗口的下拉框中选择“突出显示”,然后单击“运行效果”。

编辑
我不得不根据时间和资源限制使用我自己的解决方案,但文本框不支持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中:

                 

(它可以做一点工作,但这是一个开始)。 你有它 – 一个花哨的文本框:)

构建解决方案,新项目将出现在工具箱中 – 只需拖放到您的表单,WPF将托管在ElementHost元素中。 它的美妙之处在于你可以在WPF的视觉风格中做更多的事情,但是它托管了WPF,它为你的解决方案增加了一定的重量……

TextBox派生自己的类。 给它一个Flash()方法,开始闪烁。 只需将BackColor更改为柔和的颜色即可。 不要使用不适用于TextBox alpha。

你应该让这个类的所有实例共享一个共同的Timer,这样它们就会同时闪烁。 使计时器静态并引用计数您拥有的实例数。 在构造函数中添加,在Dispose(bool)覆盖中向下。

如果你已经开始使用WinForms了,那么凭借我有限的知识,我可以建议让第三方控件来帮忙。 一些名称是Telerik和ComponentOne。 如果你想要WinForms之类的东西,你可以使用WPF,并在XAML中开发自定义动画(我认为在创建UI状态和动画时类似于Silverlight XAML)。 除了这些,我没有经验提供任何帮助。

根据您的应用程序,一种华而不实的方法是更改​​文本框图像的灰度系数。 这当然取决于你想要投入多少时间,但这肯定是可行的。 我已经看过几个关于如何调整图像的灰度系数的教程,并且获得控件的图像是微不足道的。

也就是说,我也相信将文本框的背景颜色设置为透明是非常重要的。 根据你的措辞,我只能猜测你想要从底层控件的背景颜色淡化到文本框’背景颜色,在这种情况下问题再次微不足道。 但是如果你有背景图像,你应该重新考虑。 尽管如此,它仍然是可能的,如果这是你想要完成的,我可以为你找到如何做到这一点的链接。

快速简单的解决方案是将文本颜色和背景颜色从白色设置为当前前景色。

如果你对使用线程不感兴趣,建立在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; }