C# 中的跑马灯控件






3.58/5 (16投票s)
用 C# 编写的跑马灯控件。
概述
此应用程序演示了如何在 C# 中创建一个“字符串循环”。“字符串循环”的常见用途是在网页广告中,标语或产品名称似乎在圆形中旋转。 代码在客户端区域的中间创建一个矩形,该矩形的大小刚好足以容纳整个消息,减去任何尾随空格。 单击窗体或调整其大小将导致“字符串循环”重新启动。
需要注意的点
与其使用字符串来表示消息(“Catch Me If You Can……”)不如使用位于 System.Text
命名空间中的 StringBuilder
类更有效且更直观。 StringBuilder
允许您直接操作字符串,而无需复制常规字符串。 对 StringBuilder
的内部字符串的操作非常简单。
private void DrawMovingText()
{
Graphics grfx = CreateGraphics();
Font font = new Font( "Courier New", 20, FontStyle.Bold );
string spaces = " ";
//
// StringBuilder is used to allow for efficient manipulation of
// one string, rather than generating many separate strings
//
StringBuilder str =
new StringBuilder( "Catch Me If You Can..." + spaces );
Rectangle rect = CreateRect( grfx, str, font );
int numCycles = str.Length * 3 + 1;
for( int i = 0; i < numCycles; ++i )
{
grfx.FillRectangle( Brushes.White, rect );
grfx.DrawString( str.ToString(), font, Brushes.Red, rect );
// relocate the first char to the end of the string
str.Append( str[0] );
str.Remove( 0, 1 );
// pause for visual effect
Thread.Sleep( 150 );
}
grfx.Dispose();
}
为了避免 DrawMovingText()
占用所有 CPU 注意力,它被放置在一个工作线程上。 每次用户单击窗体或调整其大小时,线程都会被杀死并重生。 显然,如果您想改变字母“移动”的速度,只需调整线程休眠的毫秒数即可。
//
// All of these events will restart the thread that draws
// the text
//
private void Form_Load( object sender, System.EventArgs e )
{
StartThread();
}
private void Form_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
StartThread();
}
private void Form_Resize( object sender, System.EventArgs e )
{
StartThread();
}
private void label_Click(object sender, System.EventArgs e)
{
StartThread();
}
private void StartThread()
{
thread.Abort();
// give the thread time to die
Thread.Sleep( 100 );
Invalidate();
thread = new Thread(new ThreadStart(DrawMovingText));
thread.Start();
}
最后的兴趣点是如何确定包含消息的矩形的大小和位置。 Graphics
类具有一个 MeasureString
方法,该方法将为您提供传递的字符串的宽度或高度。 这些用于矩形的宽度和高度。 然后,您将这些值与窗体的尺寸结合使用,以确定矩形的原点坐标。
private Rectangle CreateRect
( Graphics grfx, StringBuilder str, Font font )
{
// + 5 to allow last char to fit
int w = (int)grfx.MeasureString(str.ToString(), font).Width + 5;
int h = (int)grfx.MeasureString( str.ToString(), font ).Height;
int x = (int)this.Width / 2 - w / 2;
int y = (int)this.Height / 2 - h;
return new Rectangle( x, y, w, h );
}