Что я делаю не так с моим пользовательским элементом управления «HorizontalRule»?

StackOverflow https://stackoverflow.com/questions/757131

Вопрос

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

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 последним, а не первым.Я не знаю, что бы это изменило, да и похоже, ничего не изменилось.

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

Это было полезно?

Решение 2

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

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

    this.Invalidate();
}

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top