在C#中滚动标签

时间:2014-09-22 16:19:02

标签: c# winforms timer label

我正在寻找一种有效的方式来滚动文本,就像网页术语中的字幕一样。

我设法使用我在网上找到的一段代码来实现这一目标:

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次后,它不再出现。

有什么我可以调整以使滚动无限吗?

2 个答案:

答案 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并使其足够大以填充该区域!