Как сделать так, чтобы метка появлялась снова, как только она выходит за пределы ширины панели - PullRequest
1 голос
/ 24 мая 2019

Я хочу, чтобы движущаяся метка казалась более приятной и плавной, чем просто повторное отображение всего объекта слева после того, как все вышло из ширины панели. Например, метка «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);
    }
}

Ответы [ 2 ]

0 голосов
/ 24 мая 2019

Попробуйте, используя метку (здесь, с именем lblMarquee и System.Windows.Forms.Timer).

Время прокрутки регулируется как Timer.Interval, так и полем с плавающей запятой (marqueeStep).
Событие Timer.Tick просто вызывает lblMarquee.Invalidate(), в результате чего элемент управления Label перерисовывается.

Когда прокручиваемый текст относительно его текущей позиции выходит за пределы Label.ClientRectangle, часть текста, которая больше не видна, закрашивается в начале Label.ClientArea:

Marquee Label

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

Несколько других реализаций, которые могут оказаться полезными:

Как следовать за концом текста в TextBox без NoWrap
Как нарисовать строку на двух несмежных областях

0 голосов
/ 24 мая 2019

Для этого нужно иметь два элемента управления метками, но это не так уж сложно.Сначала создайте резервную метку и установите ее свойства так: 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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...