【问题标题】:How to make label reappear as soon as it's going out of panel width一旦标签超出面板宽度,如何使标签重新出现
【发布时间】:2019-10-11 06:02:38
【问题描述】:

我想让一个移动的标签看起来更好更平滑,而不是在它全部超出面板宽度后重新出现在左侧。例如标签 'Hello' ,只要 'lo' 超出范围在右边我希望它重新出现在左边。有没有办法解决这个问题?

这是我现在的标签代码。

private void timer2_Tick(object sender, EventArgs e)
{          
    label5.Location = new Point(label5.Location.X + 3, label5.Location.Y);
    if (label5.Location.X > this.Width)
    {
        label5.Location = new Point(0 - label5.Width, label5.Location.Y);
    }
}

【问题讨论】:

  • 我不认为有一个简单的解决方案,因为Label 是一个单一的控件。所以它不能同时出现在右边和左边。您需要使用第二个标签来伪造它,但这是否合理取决于整个应用程序。
  • 所以基本上它不是很容易完成的,它对我的​​程序并不是很重要,所以我不会做太多的工作。不过感谢您的回复。
  • 它的 DrawToBitmap() 给你一个位图对象。您可以随心所欲地随心所欲地绘制它。
  • 我认为最好的解决方案通常是锚定或停靠控件,而不是定位它们。如果将标签锚定到其父标签的右边缘,则在调整窗口大小时它将随窗口一起移动。也许这不适用于您的情况,但至少值得考虑。

标签: c# winforms


【解决方案1】:

试试这个,使用标签(在这里,命名为lblMarqueeSystem.Windows.Forms.Timer)。

滚动时间由 Timer.Interval 和浮点字段 (marqueeStep) 共同控制。
Timer.Tick 事件只是调用lblMarquee.Invalidate(),导致 Label 控件重新绘制自身。

当滚动文本相对于其当前位置超出Label.ClientRectangle 的限制时,将在Label.ClientArea 的开头绘制不再可见的文本部分:

System.Windows.Forms.Timer marqueeTimer = new System.Windows.Forms.Timer();
string marqueeText = string.Empty;
float marqueePosition = 0f;
float marqueeStep = 4f;

private void form1_Load(object sender, EventArgs e)
{
    marqueeText = lblMarquee.Text;
    lblMarquee.Text = string.Empty;
    marqueeTimer.Tick += (s, ev) => { this.lblMarquee.Invalidate(); };
    marqueeTimer.Interval = 100;
    marqueeTimer.Start();
}

private void lblMarquee_Paint(object sender, PaintEventArgs e)
{
    var marquee = sender as Label;
    SizeF stringSize = e.Graphics.MeasureString(marqueeText, marquee.Font, -1, marqueeFormat);
    PointF stringLocation = new PointF(marqueePosition, (marquee.Height - stringSize.Height) / 2);
    stringLength = marquee.ClientRectangle.Width - stringLocation.X;

    e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
    e.Graphics.DrawString(marqueeText, marquee.Font, Brushes.Black, stringLocation, marqueeFormat);
    if (marqueePosition >= marquee.ClientRectangle.Width) marqueePosition = 0f;

    if (stringSize.Width + stringLocation.X > marquee.ClientRectangle.Width) {
        PointF partialStringPos = new PointF(-stringLength, (marquee.Height - stringSize.Height) / 2);
        e.Graphics.DrawString(marqueeText, marquee.Font, Brushes.Black, partialStringPos, marqueeFormat);
    }
    marqueePosition += marqueeStep;
}

您可能会发现其他一些有用的实现:

How to follow the end of a text in a TextBox with no NoWrap
How to draw a string on two not adjacent areas

【讨论】:

    【解决方案2】:

    您需要有两个标签控件才能做到这一点,但这并不难。首先,创建一个备份标签并将其属性设置为类似于label5

    // A backup label for our scrolling label5
    private Label label5_backup;
    
    private void Form1_Load(object sender, EventArgs e)
    {
        label5.Text = "This is a scrolling label!";
    
        // Set label5_backup to look like label5
        label5_backup = new Label
        {
            Size = label5.Size,
            Text = label5.Text,
            Top = label5.Top,
            Visible = false
        };
    
        Controls.Add(label5_backup);
    
        timer2.Interval = 1;
        timer2.Start();
    }
    

    然后,在Tick 事件中,当我们的label5 开始离开客户矩形时,将我们的备份标签设置为距表单左侧适当的距离,以便它开始出现在另一侧.一旦label5 完全脱离表单,设置它的位置以匹配备份标签,然后再次隐藏备份标签。

    请注意,您可以只设置Left 属性,而不是每次都创建一个新的Location 点,这样可以稍微简化代码:

    private void timer2_Tick(object sender, EventArgs e)
    {
        label5.Left++;
    
        // If label5 starts to go off the right, show our backup on the left side of the form
        if (label5.Right > ClientRectangle.Width)
        {
            label5_backup.Left = label5.Right - ClientRectangle.Width - label5.Width;
            label5_backup.Visible = true;
        }
    
        // If label5 is all the way off the form now, set it's location to match the backup
        if (label5.Left > ClientRectangle.Width)
        {
            label5.Location = label5_backup.Location;
            label5_backup.Visible = false;
        }
    }
    

    另外,如果你想让滚动更平滑,每次只将Left 增加1 并将timer2.Interval 减少到之前的三分之一(除非它已经在1)。

    【讨论】:

    • 由于某种原因对我不起作用,它仍然和以前一样。
    猜你喜欢
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    相关资源
    最近更新 更多