我正在寻找一种有效的方式来滚动文本,就像网页术语中的字幕一样。
我设法使用我在网上找到的一段代码来实现这一目标:
private int xPos = 0, YPos = 0;
private void Form1_Load(object sender, EventArgs e)
{
//link label
lblText.Text = "Hello this is marquee text";
xPos = lblText.Location.X;
YPos = lblText.Location.Y;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (xPos == 0)
{
this.lblText.Location = new System.Drawing.Point(this.Width, YPos);
xPos = this.Width;
}
else
{
this.lblText.Location = new System.Drawing.Point(xPos, YPos);
xPos -= 2;
}
}
代码非常简单,它使用了一个计时器刻度事件。
最初效果很好,但滚动3到4次后,它不再出现。
有什么我可以调整以使滚动无限吗?
答案 0 :(得分:1)
尝试:
private void timer1_Tick(object sender, EventArgs e)
{
if (xPos <= 0) xPos = this.Width;
this.lblText.Location = new System.Drawing.Point(xPos, YPos);
xPos -= 2;
}
你提到它已经切断了&#39;如果字符串长于表单宽度。我认为你的意思是标签一碰到左侧就跳回到表格的右侧,这意味着你无法阅读全文?
如果是这样,您可以设置“最小左”和“最小值”。标签的宽度是负面的。这将允许标签在重置之前完全滚动表单:
private void timer1_Tick(object sender, EventArgs e)
{
// Let the label scroll all the way off the form
int minLeft = this.lblText.Width * -1;
if (xPos <= minLeft) xPos = this.Width;
this.lblText.Location = new Point(xPos, yPos);
xPos -= 2;
}
或者,您可以设置“最低左边”&#39;是标签宽度和表格宽度之间差异的负面因素,因此在最右边的字符显示之前它不会重置:
private void timer1_Tick(object sender, EventArgs e)
{
// Ensure that the label doesn't reset until you can read the whole thing:
int minLeft = (lblText.Width > this.Width) ? this.Width - lblText.Width : 0;
if (xPos <= minLeft) xPos = this.Width;
this.lblText.Location = new Point(xPos, yPos);
xPos -= 2;
}
许多其他选择。就像让多个标签在旋转中背靠背运行一样,所以永远不会有任何空白文字!您可以计算出动态生成的标签数量(基于宽度和表格宽度之间的差异)并在Timer事件中处理它们的位置。
答案 1 :(得分:1)
如果您通过添加空白填充标签直到它具有您想要的长度,这可能看起来更好:
private void timer1_Tick(object sender, EventArgs e)
{
lblText.Text=
lblText.Text.Substring(1) + lblText.Text.Substring(0,1);
}
尽管如此,添加适量的空白可能会有点挑战。你需要在Form.Resize上做到这一点!做正确的事情比人们想象的要复杂一点。
完美的选框将结合像素运动和翻转效果,可能是所有者绘制标签,也许就像这个'真实选框',所以80年代; - )
class Marquee : Label
{
public Timer MarqueeTimer { get; set; }
public int Speed { get; set; }
public int yOffset { get; set; }
public void Start() { MarqueeTimer.Start(); }
public void Stop() { MarqueeTimer.Stop(); }
private int offset;
SolidBrush backBrush ;
SolidBrush textBrush ;
public Marquee()
{
textBrush = new SolidBrush(this.ForeColor);
backBrush = new SolidBrush(this.BackColor);
yOffset = 0;
Speed = 1;
MarqueeTimer = new Timer();
MarqueeTimer.Interval = 25;
MarqueeTimer.Enabled = true;
MarqueeTimer.Tick += (aSender, eArgs) =>
{
offset = (offset - Speed);
if (offset < -this.ClientSize.Width) offset = 0;
this.Invalidate();
};
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillRectangle(backBrush, e.ClipRectangle);
e.Graphics.DrawString(this.Text, this.Font, textBrush, offset, yOffset);
e.Graphics.DrawString(this.Text, this.Font, textBrush,
this.ClientSize.Width + offset, yOffset);
}
}
看起来非常流畅,不需要外部代码,但需要启动,停止和设置速度,也许不需要MarqueeTimer Intervall。所有常规属性都可以在Designer中使用,只需设置AutoSize=false
并使其足够大以填充该区域!