我有一个表单,显示消息队列和消息数量,这些消息数量可以更改。实际上,当消息数量增加时,我希望闪烁标签(队列长度),以改善表单的可用性。
我应该实现自定义控件并使用额外的线程或计时器来更改标签的颜色吗?有人实现了这样的功能吗?实现这种行为的最佳解决方案是什么(资源和性能降级最少)?
解决方案: 在表单组件中使用计时器,可以限制每秒钟的动画次数并实现淡出效果,以外部控件背景颜色为基础。
解决方案: 在表单组件中使用计时器,可以限制每秒钟的动画次数并实现淡出效果,以外部控件背景颜色为基础。
以下内容使用async
和await
进行闪烁:
private async void Blink(){
while (true){
await Task.Delay(500);
label1.BackColor = label1.BackColor == Color.Red ? Color.Green : Color.Red;
}
}
_continueBlink
内添加一个布尔变量的检查,只要它为真就继续循环,否则离开循环。然后你可以在其他地方将其设置为false
以退出闪烁循环。 - IdontCareAboutReputationPoints我知道这是一个非常老的帖子,但是任何想要找到比布尔解决方案更加多功能的人可能会从以下内容中受益:
using System.Diagnostics;
using System.Threading.Tasks;
private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
{
var sw = new Stopwatch(); sw.Start();
short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
while (true)
{
await Task.Delay(1);
var n = sw.ElapsedMilliseconds % CycleTime_ms;
var per = (double)Math.Abs(n - halfCycle) / halfCycle;
var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R;
var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G;
var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B;
var clr = Color.FromArgb(red, grn, blw);
if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
}
}
你可以这样调用:
SoftBlink(lblWarning, Color.FromArgb(30, 30, 30), Color.Red,2000,false);
SoftBlink(lblSoftBlink, Color.FromArgb(30, 30, 30), Color.Green, 2000,true);
Timer timer = new Timer();
timer.Interval = 500;
timer.Enabled = false;
timer.Start();
if( messagesNum > oldMessagesNum)
timer.Tick += new EventHandler( timer_Tick );
else
timer.Tick -= timer_Tick;
void timer_Tick( object sender, EventArgs e )
{
if(messageLabel.BackColor == Color.Black)
messageLabel.BackColor = Color.Red;
else
messageLabel.BackColor = Color.Black;
}
以下是一个非常简单的实现,可在表单内部使用。您也可以使用相同的代码创建自定义控件,并将 Timer.Start()
放置在该控件的方法中。
你能使用动态的 .gif
图片来代替(或许作为数字的背景)吗?这会让它看起来像老式的网页,但这可能有效。
你可以在这里使用 Timer
类。
这是我实现的内容。
在 Button_click 事件上标签颜色闪烁。
//click event on the button to change the color of the label
public void buttonColor_Click(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 500;// Timer with 500 milliseconds
timer.Enabled = false;
timer.Start();
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
//label text changes from 'Not Connected' to 'Verifying'
if (labelFirst.BackColor == Color.Red)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Verifying";
}
//label text changes from 'Verifying' to 'Connected'
else if (labelFirst.BackColor == Color.Green)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Connected";
}
//initial Condition (will execute)
else
{
labelFirst.BackColor = Color.Red;
labelFirst.Text = "Not Connected";
}
}
这就是我最终的做法
public partial class MemberDisplay : Form
{
public string Input;
public int MASS_STOP = 1;
public MemberDisplay(string msg)
{
InitializeComponent();
State_Entry();
Input = msg;
}
public void State_Entry()
{
this.SpecialFocus.Select();
this.lbl_TimerTest.Hide();
}
private async void RunBlinkyTest(string msg)
{
while (msg == "GO" && (MASS_STOP == 0))
{
await Task.Delay(500);
lbl_TimerTest.ForeColor =
lbl_TimerTest.ForeColor == Color.Red ?
Color.Black :
Color.Red;
if (msg == "STOP" && (MASS_STOP == 1)) { return; }
}
}
private void btn_TimeTest_Click(object sender, EventArgs e)
{
if (btn_TimeTest.Text == "GO")
{
this.lbl_TimerTest.Show();
MASS_STOP = 0;
RunBlinkyTest("GO");
btn_TimeTest.Text = "STOP";
return;
}
if (btn_TimeTest.Text == "STOP")
{
MASS_STOP = 1;
RunBlinkyTest("STOP");
this.lbl_TimerTest.ForeColor = Color.Black;
this.lbl_TimerTest.Hide();
btn_TimeTest.Text = "GO";
return;
}
}
}