【问题标题】:.NET CF double-buffering when painting over base control在基础控件上绘制时.NET CF 双缓冲
【发布时间】:2014-10-07 08:04:06
【问题描述】:

我已经为一些完全由用户绘制的 .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 方法绘制它的标题。

【问题讨论】:

    标签: .net compact-framework double-buffering


    【解决方案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 对象执行您想要的操作,该对象将绘制到缓冲区而不是屏幕上。

    如果您希望孩子能够完全覆盖基础绘画,只需将基础绘画逻辑移动到虚拟方法中即可。

    【讨论】:

    • 我的控件继承了 System.Windows.Forms.DataGrid。我不确定 DataGrid 是如何绘制的。
    • 我的控件继承了 System.Windows.Forms.DataGrid。我不确定 DataGrid 是如何绘制的。当使用我的 CustomPaintHeaders 方法和 CustomPaintRows 方法(当前仅绘制一个白色矩形来代替网格)时,我可以成功地进行双缓冲,类似于您在上面所做的那样,使用新的 Bitmap 并从中使用 Graphics 对象.有没有办法让 DataGrid 的普通 OnPaint 绘制到缓冲区图像? (所以我可以只调用它和 CustomPaintHeaders,而不必去实际实现 CustomPaintRows)
    • 您已经查看了一些专门用于格式化 CF DataGrids 的资源? codeproject.com/Articles/20268/…
    • 是的,我实际上使用该页面来帮助我根据不同的条件使某些整行颜色不同。
    • 不知道如何将绘画从 MyBase.OnPaint 应用到缓冲区,但我决定以简单的方式解决我的问题 - 使用双缓冲进行自定义标题绘画,并设置 RowHeadersVisible = False并在我的自定义标题下方开始绘制行。
    猜你喜欢
    • 1970-01-01
    • 2010-10-05
    • 2014-08-08
    • 2010-12-22
    • 2012-10-23
    • 2012-02-11
    • 1970-01-01
    • 2013-01-17
    • 2014-04-07
    相关资源
    最近更新 更多