简体   繁体   English

在基础控件上绘画时的.NET CF双缓冲

[英].NET CF double-buffering when painting over base control

I've used double-buffering for some .NET Compact Framework controls that are entirely user-drawn, but I'm having trouble figuring out how I can use double-buffering for a control that inherits from another control and paints over it. 我已经对完全由用户绘制的某些.NET Compact Framework控件使用了双缓冲,但是在弄清楚如何对从另一个控件继承并对其进行绘制的控件使用双缓冲时遇到了麻烦。

I have a control based on DataGrid, that paints over the headers. 我有一个基于DataGrid的控件,它可以绘制标题。

My OnPaint method is: 我的OnPaint方法是:

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

CustomPaintHeaders just paints on top of the basic DataGrid headers with some custom drawing. CustomPaintHeaders只是在基本DataGrid标头的顶部绘制一些自定义图形。 Occassionally, I get flickering where I see the basic DataGrid headers get painted, but without my custom-drawn stuff on top. 有时,我会在闪烁的位置看到基本的DataGrid标头被绘制,但上面没有我自定义的内容。

Is it possible to use double-buffering, and have the painting that's done by MyBase.OnPaint applied to the buffer image? 是否可以使用双缓冲,并将MyBase.OnPaint完成的绘制应用于缓冲图像?

Edit: As mentioned in my comment, I am able to do double buffering using this code: 编辑:如我的评论中所述,我可以使用以下代码进行双缓冲:

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

And this works fine without flickering, but I'd like to avoid having to implement CustomPaintRows, and just let DataGrid's OnPaint handle that part for me, and then draw over it's headers with my CustomPaintHeaders method. 而且它可以正常工作而不会闪烁,但是我要避免实现CustomPaintRows,而只让DataGrid的OnPaint为我处理该部分,然后使用CustomPaintHeaders方法绘制它的标题。

Double-buffering in the CF is a manual process, so I would assume that your base class holds an Image or Bitmap onto which it is drawing? CF中的双缓冲是一个手动过程,因此我假设您的基类拥有要在其上绘制图像或位图的图像? It depends on exactly how you're doing your painting but you can either make that Image protected or you can do something slightly more complex like this: 这完全取决于您的绘画方式,但是您可以使Image 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);
}

Then in your child, simply override the new OnPaint and do what you want with the incoming Graphics object, which paints onto the buffer, not the screen. 然后在您的孩子中,只需覆盖新的OnPaint并使用传入的Graphics对象(该对象将绘制在缓冲区而不是屏幕上)进行所需的操作。

If you want the child to be able to completely override base painting, just move the base painting logic into the virtual method. 如果希望孩子能够完全覆盖基础绘画,只需将基础绘画逻辑移到虚拟方法中即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM