2014-09-22 83 views
1

我正在尋找一種滾動文本的有效方式,就像網頁術語中的選取框一樣。在C中滾動標籤#

我設法實現這一目標用了一段代碼我在網上找到:

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次後,它不會再出現。

有什麼我可以調整,使滾動無限?

+3

還記得我們在90年代停止使用跑馬燈嗎? :) – DavidG 2014-09-22 16:21:08

+3

當'xPos - = 2;'將位置減少到-1時,您會發生什麼? – 2014-09-22 16:21:13

+0

爲什麼你不能在一個div和使用'選取框方向等... – MethodMan 2014-09-22 16:26:20

回答

0

嘗試:

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; 
} 

你提到,「切斷」如果字符串比表格寬度更長。我假設你的意思是,標籤一碰到左側就會跳回到表單的右側,這意味着你無法閱讀全文?

如果是這樣,您可以將Label的'Minimum Left'設置爲它的寬度的負值。這將允許標籤重置前關閉的形式完全滾動:

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; 
} 

或者,你可以設置的最低左派「是標籤寬度和表格寬度之差的不利,從而使直到顯示最右邊的字符纔會重置:

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事件中的位置。

+0

完美,非常感謝! – 2014-09-22 16:51:43

+0

如果字符串比表格寬度長,則切斷它 – 2014-09-22 20:35:27

+0

您需要執行以下操作:'if(xPos <= 0)xPos = this.Width - lblText.Width;' – TaW 2014-09-22 20:40:56

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。所有常規屬性將從設計器中運行,只需設置AutoSize=false並使其足夠大以填充該區域!

+0

你試過這個嗎?它甚至不會編譯 – 2014-09-22 19:45:33

+0

當然我試過了。但是我收到了一個類型。很難找到複製和粘貼錯誤..我希望我沒有把你搞糊塗! – TaW 2014-09-22 20:13:48

+0

是的,有一個錯字,但它沒有給出預期的效果,所有的文本都收緊了,在結尾和開始之間沒有空格。也請查看我的[評論](https://stackoverflow.com/users/3850487/meda-cool)@rufus下的答案 – 2014-09-22 20:34:47