Что я делаю не так с моим пользовательским элементом управления «HorizontalRule»? - PullRequest
0 голосов
/ 16 апреля 2009

Я написал следующий (очень простой) элемент управления для использования в приложении (комментарии для краткости удалены):

public partial class HorizontalRule : Control
{
    public HorizontalRule()
    {
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        var g = e.Graphics;

        var rect = new Rectangle(
            this.ClientRectangle.Left,
            this.ClientRectangle.Height / 2 + 1, 
            this.ClientRectangle.Width,
            1);

        ControlPaint.DrawBorder3D(g, rect, Border3DStyle.Etched);

        return;
    }
}

Отказ от ответственности: я новичок в рисовании своих собственных средств управления.

Я решил нарисовать линию таким образом, основываясь на рекомендации в руководствах по Vista UX , в которой для разделителей предлагается запечатленный прямоугольник высотой 1.

Когда статический, это выглядит хорошо, но я заметил, что я получаю перерисовывающие артефакты, если я помещаю этот элемент управления в окно и изменяю его размер (например, через привязку). Я перерисовываю свою границу по всей ширине моего клиентского прямоугольника, но на самом деле она не рисуется. Включение DoubleBuffered в конструкторе HorizontalRule или в форме, в которую оно встроено, также не имеет значения.

Что я делаю не так?

Обновление:

Согласно предложению, я попытался вызвать base.OnPaint последним, а не первым. Я не знаю, что бы это изменило, и, похоже, это тоже ничего не изменило.

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

Ответы [ 3 ]

1 голос
/ 16 апреля 2009

Не звоните base.OnPaint или не звоните в последнюю очередь (сейчас я не могу вспомнить).

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

1 голос
/ 16 апреля 2009

Я могу взломать решение, которое не приводит к артефактам, переопределив OnResize (), чтобы сделать недействительным весь элемент управления:

protected override void OnResize(EventArgs e)
{
    base.OnResize(e);

    this.Invalidate();
}

Однако я не уверен, что это «правильное» решение.

0 голосов
/ 16 апреля 2009

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

...