按照需求要做这么一个控件,通过简单设置控件的字符串属性为待展现字符串,字符串就可自动在控件上由下往上滚动,类似千千静听滚动歌词字幕功能,但是控件大小可调节,需要字符串自适应控件大小,需要展示的字符串比较多,这是个难点。我尝试过四种思路:
一:利用时钟移动控件坐标。
二:利用时钟移动控件内部标签。这两中思路显然不行,第二中可展示的字符串有限。
三:移动文本,按一定时间拼接一次字符串,造成字符滚动的假象,但是这只能左右移动。vb.net代码如下:


Public Class Form1
Private str1, str2 As String
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Label1.Text = str1
Dim i As Integer, j As String
If str1 = "" Then
Timer1.Enabled = False
Timer2.Enabled = True
Else
i = Val(Len(str1)) '计算字符串个数
j = Microsoft.VisualBasic.Right$(str1, (i - 1)) '取出每一个字符串除第一个字符以后的字符串
str1 = j
If str1.Length = 1 Then '只剩下最后一个字时再从头出现字符串,循环出现
str1 = str1 + str2
End If
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim str3 As String = " " '用一定长度的空格留出下一次重复出现的间隙
str1 = str3 + "29届奥林匹克运动会将于2008年8月8日至24日在中国首都北京举行,共将举行28个大项,38个分项的比赛,产生302块金牌。将有2万多名运动员、教练员和官员参加北京奥运会。本届奥运会主题歌:《我和你》主唱歌手为:刘欢、莎拉布莱曼"
str2 = str1
Me.Label1.Text = ""
Me.Timer1.Interval = 400 '控制字符移动速度
Me.Timer1.Enabled = True
End Sub
End Class
四:把需要展示的字符串写到一副图像上,然后把图像写到图形设备上。实现代码如下,但是这个程序不完善,我在内存中固定设置了控件宽度*1000的bitmap图像,所以至多滚动这一副图像面接容量的字符串,然后我让时钟大约在500秒内在控件上滚动完这一副图像。这样的普遍现象是,譬如展现字符串几百个,在滚动完这些字符后,实际上程序还在运行,浪费资源。问题的主要困难在于,将一串字符串写入图像后,如何才能知道,这些字符串的面积或者说高度有多大?那就要计算字符大小,字符间距,字符个数,控件宽度之间的关系。也能计算,不过字符的间距不随字体的差异,大小而变化吗?
另外,不知道能否把web窗体嵌入到winform窗体中,因为在web窗体中实现字符串滚动比较简单。


/*
* 本控件实现思路:在内存中放一bitmap图像对象,将需要滚动的字符串写入图像中,利用图形设备graphic获得控件区域,利用时钟计时滚动图像到控件上。
* 注意:控件所能滚动展示的字符串个数,取决于内存bitmap图像大小和时钟计时长短,程序设计bitmap 为控件宽度*1000像素,时钟在500秒后,停止计时。
* 用法: LoopBar1.DisplayString=" display string ";设置滚动字符串
* LoopBar1.LoopBackColor=Color.Black; 设置控件背景色,可省略,默认为银白色
* LoopBar1.LoopFontColor=Color.Red; 设置字体颜色 ,可省略,默认为黑色
* LoopBar1.LoopFontSize=12; 设置字体大小,可省略,默认大小为12
* LoopBar1.LoopInterval=500; 设置滚动频率,可省略,默认为500
* LoopBar1.Start(); 控件启动
*
* LoopBar1.Stop();暂停滚动
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace CustomControlsLibrary
{
public partial class LoopBar : UserControl
{
private string displayString = null;
private Timer timer;
private Graphics g;
private Pen p;
private Font f;
private Brush b;
private int graduation;
private RectangleF recF = RectangleF.Empty;
private Bitmap templet = null;
private Bitmap lastbmp = null;
private Color backColor = Color.WhiteSmoke;//控件默认颜色
private Color fontColor = Color.Black;//控件展现字体默认为黑色
private int fontSize = 12;//控件展现字体默认大小为12
public LoopBar()
{
InitializeComponent();
timer = new Timer();
timer.Interval = 500;
this.timer.Tick += new EventHandler(timer_Tick);
timer.Stop();
graduation = 0;
}
private void timer_Tick(object sender, EventArgs e)
{
this.BitmapToGraphics();
graduation += 5;
if (graduation == 5000) //计数器在加到5000后,时间为500秒后,停止计时
{
if (this.timer.Enabled == true)
{
this.timer.Stop();
this.timer.Dispose();
}
}
}
/// <summary>
/// 在内存中建立一个控件宽度*1000图像,然后将字符串绘于图像上。
/// </summary>
protected void StringToBitmap()
{
p = new Pen(Color.Black, 2);
f = new Font(FontFamily.GenericSerif, this.fontSize, FontStyle.Regular, GraphicsUnit.Pixel);
b = new SolidBrush(this.fontColor);
recF = new RectangleF(0, 0, this.Width , 1000);
templet = new Bitmap(this.Width , 1000);
g = Graphics.FromImage(templet);
g.DrawString(this.displayString, f, b, recF);
lastbmp = (Bitmap)templet.Clone();
g.Dispose();
}
/// <summary>
/// 利用坐标变换,滚动图像到图形设备上
/// </summary>
protected void BitmapToGraphics()
{
g = this.CreateGraphics();
g.Clear(this.backColor);
g.DrawImageUnscaled(templet, new Rectangle(0, -1 * (-1 * this.Height + graduation), this.Width , -1 * (-2 * this.Height + graduation)));
g.Dispose();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//重绘内容
}
public void Start()
{
if (this.timer.Enabled == false)
{
this.timer.Start();
}
}
public void Stop()
{
if (this.timer.Enabled == true)
{
this.timer.Stop();
}
}
[
Category("LoopBarProperty"),
Description("设置需要滚动出现的字符串,最多可设置控件宽度*1000面积容量的字符数")
]
public string DisplayString
{
get
{
return this.displayString;
}
set
{
if (value != null && value != "")
{
this.displayString = value;
this.StringToBitmap();
}
}
}
[
Category("LoopBarProperty"),
Description("指定控件的背景颜色,默认为银白色")
]
public Color LoopBackColor
{
get
{
return this.backColor;
}
set
{
this.backColor = value;
}
}
[
Category("LoopBarProperty"),
Description("指定控件字体的颜色,默认为黑色")
]
public Color LoopFontColor
{
get
{
return this.fontColor;
}
set
{
this.fontColor = value;
this.StringToBitmap();
}
}
[
Category("LoopBarProperty"),
Description("指定控件字体的大小,以像素为单位,默认为12")
]
public int LoopFontSize
{
get
{
return this.fontSize;
}
set
{
if (value > 0)
{
this.fontSize = value;
this.StringToBitmap();
}
}
}
[
Category("LoopBarProperty"),
Description("指定控件字体滚动频率,默认为500,单位为毫秒")
]
public int LoopInterval
{
get
{
return this.timer.Interval;
}
set
{
this.timer.Interval = value;
}
}
}
}