Двойная буферизация .NET CF при рисовании поверх базового элемента управления

Я использовал двойную буферизацию для некоторых элементов управления .NET Compact Framework, которые полностью создаются пользователем, но мне трудно понять, как я могу использовать двойную буферизацию для элемента управления, который наследуется от другого элемента управления и закрашивает его.

У меня есть элемент управления на основе DataGrid, который закрашивает заголовки.

Мой метод OnPaint:

Protected Overrides Sub OnPaint(ByVal pe as System.Windows.Forms.PaintEventArgs)
    MyBase.OnPaint(pe)
    CustomPaintHeaders(pe.Graphics)
End Sub

CustomPaintHeaders просто рисует поверх основных заголовков DataGrid с некоторым настраиваемым рисунком. Иногда я начинаю мерцать, когда вижу, что основные заголовки DataGrid отрисовываются, но без моих настраиваемых элементов наверху.

Можно ли использовать двойную буферизацию и применить рисование, выполненное MyBase.OnPaint к изображению в буфере?

Изменить: как упоминалось в моем комментарии, я могу выполнять двойную буферизацию, используя этот код:

Protected Overrides Sub OnPaint(ByVal pe as System.Windows.Forms.PaintEventArgs)
    Using currentRender as Bitmap = New Bitmap(Me.Width, Me.Height)
        Using gr as Graphics = Graphics.FromImage(currentRender)
            CustomPaintHeaders(gr)
            CustomPaintRows(gr)
        End Using
    End Using
End Sub

Private Sub CustomPaintHeaders(ByVal graphics as Graphics)

    'Custom drawing stuff in place of DataGrid column headers

End Sub

'TEMP - draws rectangle in place of grid rows
Private Sub CustomPaintRows(ByVal graphics as Graphics)
    graphics.DrawRectangle(New Pen(Me.ForeColor), 0, 20, Me.Width, Me.Height) 
End Sub

И это отлично работает без мерцания, но я бы хотел избежать реализации CustomPaintRows и просто позволить DataGrid OnPaint обрабатывать эту часть за меня, а затем рисовать поверх ее заголовков с помощью моего метода CustomPaintHeaders.


person derekj    schedule 13.08.2014    source источник


Ответы (1)


Двойная буферизация в CF - это ручной процесс, поэтому я предполагаю, что ваш базовый класс содержит изображение или растровое изображение, на котором он рисует? Это зависит от того, как именно вы рисуете, но вы можете либо сделать это Изображение protected, либо сделать что-то более сложное, например:

protected virtual void OnPaint(graphics bufferGraphics) { } 

void OnPaint(PaintEventArgs pe)
{
    var buffer = new Bitmap(this.Width, this.Height);
    var bufferGraphics = Graphics.FromImage(buffer);

    // do base painting here
    bufferGraphics.DrawString(....);
    // etc.

    // let any child paint into the buffer
    OnPaint(bufferGraphics);

    // paint the buffer to the screen
    pe.Graphics.DrawImage(buffer, 0, 0);
}

Затем в своем дочернем элементе просто переопределите новый OnPaint и сделайте то, что вы хотите, с входящим объектом Graphics, который рисует в буфере, а не на экране.

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

person ctacke    schedule 14.08.2014
comment
Мой элемент управления наследует System.Windows.Forms.DataGrid. Я не уверен, как DataGrid рисует. - person derekj; 16.08.2014
comment
Мой элемент управления наследует System.Windows.Forms.DataGrid. Я не уверен, как DataGrid рисует. Я могу успешно выполнить двойную буферизацию, аналогично тому, как вы это сделали выше, используя новое растровое изображение и используя из него объект Graphics при использовании моего метода CustomPaintHeaders и метода CustomPaintRows (который в настоящее время просто рисует белый прямоугольник вместо сетки) . Есть ли способ сделать обычную отрисовку OnPaint DataGrid в буферное изображение? (поэтому я могу просто назвать это и CustomPaintHeaders, и мне не нужно идти и фактически реализовывать CustomPaintRows) - person derekj; 16.08.2014
comment
А вы уже просмотрели некоторые ресурсы специально по форматированию CF DataGrids? codeproject.com/Articles/20268/ - person ctacke; 16.08.2014
comment
Да, я действительно использовал эту страницу, чтобы помочь мне сделать определенные целые строки по-разному окрашенными в зависимости от разных условий. - person derekj; 18.08.2014
comment
Не понял, как применить рисование из MyBase.OnPaint к буферу, но я решил просто решить мою проблему простым способом - сделать мою собственную отрисовку заголовка с двойной буферизацией, установить RowHeadersVisible = False и начать рисование строк ниже моего пользовательского заголовки. - person derekj; 18.08.2014