【问题标题】:Panel DoubleBuffered property stopped the drawing, is invisiblePanel DoubleBuffered 属性停止绘图,不可见
【发布时间】:2011-07-06 12:31:14
【问题描述】:

我有一个组件,一个继承的 Panel,我在其中重写 OnPaint 事件以绘制一个 500 点的图形。因为我需要在图表上做一些选择,所以它在闪烁。我找到了这个 DoubleBuffered 属性,但是当我将它设置为 True 时,在面板构造函数中,绘图消失了。我调试它,我看到绘图方法仍在执行,但面板上没有任何内容。 有谁知道为什么会这样?

这是 .NET 3.5 - C#。 Winforms 应用程序

        try
        {
            Graphics g = e.Graphics;

            //Draw _graphArea:
            g.DrawRectangle(Pens.Black, _graphArea);

            _drawingObjectList.DrawGraph(g, _mainLinePen, _diffLinePen, _dotPen, _dotBrush, _notSelectedBrush, _selectedBrush);

            DrawSelectionRectangle(g);

            g.Dispose();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

面板后代构造函数:

        this.BackColor = Color.White;
        this.SetStyle(ControlStyles.ResizeRedraw, true);
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.UpdateStyles(); 

【问题讨论】:

  • 我认为这是.Net?语言?
  • @rene 是的。对不起。 C#。现在问题来了。
  • 你能告诉我们你的绘图代码吗?
  • 将 DoubleBuffered 属性更改为 true 是 only 发生变化的事情吗?
  • 是的,代码会很有帮助。听起来默认背景正在覆盖您的图像。您可能没有设置 UserPaint 和 AllPaintingInWMPaint 类位。

标签: c# winforms drawing gdi panel


【解决方案1】:

尝试改用ControlStyles.OptimizedDoubleBuffered。它更快,通常效果更好。确保ControlStyles.AllPaintingInWmPaintControlStyles.UserPaint 也已启用。

现在,OnPaint() 应该是唯一绘制到窗口的内容,并且只能从无效或使用 Refresh() 调用此方法;你绝不能自己打电话给OnPaint()。不要处置Graphics 对象。如果您未能满足这些条件中的任何一个,则可能会出现闪烁和各种其他绘图错误。

class MyControl : UserControl
{
    public MyControl()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    }

    protected override void  OnPaint(PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Red);
    }

    void RandomEventThatRequiresRefresh(object sender, EventArgs e)
    {
        Refresh();
    }
}

【讨论】:

  • 我正在做这一切。我使用 this.Invalidate() 来刷新图表。但是,正如您在我的代码中看到的,我不在 OnPaint 中进行绘图。我还有其他可以绘制的对象。
  • @elector 可以从另一个方法中提取,只要该方法由OnPaint 或被调用者调用并且您始终使用事件处理程序提供给您的e.Graphics 对象.看看删除 g.Dispose 调用是否有帮助。我第一次看到这个问题时没有注意到。
  • 是的!删除 g.Dispose 解决了它!我不知道为什么会这样,我正在遵循 C# Graphics book 中的示例,而这种平静的代码来自那里!谢谢
猜你喜欢
  • 2012-09-27
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-02
  • 1970-01-01
相关资源
最近更新 更多