Обновление PictureBox вызывает мерцание слоев выше

1

Я пытаюсь прочитать данные из портов и показать, что на циферблате. фон - это PictureBox, содержащий изображение круговой шкалы, дающее показания, а Lineshape используется для представления циферблата. PictureBox был "отправлен назад", чтобы обеспечить видимость Lineshape. Я прилагаю репрезентативные коды: если я это сделаю:

    private void timer1_Tick(object sender, EventArgs e)
    {
        ang += 2.0 * Math.PI / 180.0;
        lineShape1.X1 = Convert.ToInt32(lineShape1.X2 - r * Math.Sin(ang));
        lineShape1.Y1 = Convert.ToInt32(lineShape1.Y2 - r * Math.Cos(ang));

    }

то он оставляет след на PictureBox.

Но если я использую функцию Refresh для PictureBox, тогда циферблат будет мерцать. я пробовал с интервалами таймера 10, 15, 20, 50 и 100, но проблема сохраняется.

    private void timer1_Tick(object sender, EventArgs e)
    {
        ang += 2.0 * Math.PI / 180.0;
        lineShape1.X1 = Convert.ToInt32(lineShape1.X2 - r * Math.Sin(ang));
        lineShape1.Y1 = Convert.ToInt32(lineShape1.Y2 - r * Math.Cos(ang));
        pictureBox1.Refresh();
    }

Для реальной проблемы невозможно увеличить интервал. Что я могу сделать, чтобы показать плавное изменение набора?

  • 3
    Не используйте LineShape. Вместо этого используйте e.Graphics.DrawLine () в графическом окне 'Событие рисования. Вызовите pictureBox1.Invalidate (), чтобы попросить перекрасить.
  • 0
    Я новичок в использовании компонента pictureBox. так что можете разобрать большую часть этого ответа, пока Ларри не добавил код. Спасибо вам обоим..
Теги:
winforms
picturebox

2 ответа

4
Лучший ответ

Как предложил @Hans Passant, вы не должны использовать объект LineShape. Это пример кода, который реализует его предложение (быстрое, непроверенное):

private void timer1_Tick(object sender, EventArgs e)
{
    pictureBox1.Invalidate();
}

void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    ang += 2.0 * Math.PI / 180.0;
    var X1 = Convert.ToInt32(X2 - r * Math.Sin(ang));
    var Y1 = Convert.ToInt32(Y2 - r * Math.Cos(ang));

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    e.Graphics.DrawLine(
        new Pen(Color.Yellow, 1f),
        new Point(X1, Y1), 
        new Point(X2, Y2 ));
}

Также попробуйте установить this.DoubleBuffered = true; чтобы избежать проблескивания.

  • 0
    Большое спасибо. рисование линий не очень гладко, но, тем не менее, служит основной цели. даже с интервалом в 10 миллисекунд заметного мерцания нет ... :)
  • 0
    Черт, я забыл это ... Я немного обновил код, чтобы добавить сглаживание
Показать ещё 2 комментария
0

Известно, что GDI+ имеет этот эффект в целом. Вот почему WinForms обычно заменяются WPF и XAML. Я думаю, что IIRC, PictureBox особенно подвержен этой проблеме. Что вам нужно сделать, это выполнить все ваши "рисунок" на изображении в PictureBox outsde в PictureBox. Как только весь ваш чертеж будет завершен, обновите PictureBox новым изображением.

Однако, если вы рисуете новые изображения очень быстро и впоследствии обновляете PictureBox, вы все равно будете мерцать. PictureBox был просто не предназначен для этого варианта использования. Он разработал более или менее для отображения статического изображения (или того, которое может время от времени меняться, но не на высокой частоте).

  • 0
    Этот ответ бесполезен. Это не помогает решить проблему.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню