Paint Event e.Graphics.DrawImage 似乎没有遵循双缓冲
Paint Event e.Graphics.DrawImage doesn't seem to follow double buffering
目前正在重写旧代码,其中我使用图形函数绘制基于位置数据的交互式矢量地图。
回到使用 .NET 4.7 时,我可以简单地将我的东西绘制到位图中,执行 Graphics gr = Panel.CreateGraphics(),然后执行 gr.DrawImage()。我从来没有启用双缓冲,而且它总是工作正常。
现在我在 .NET 5 中,仍然使用 WinForms,并尝试根据 Paint 事件做一些更好的事情,并在与之交互时使组件无效。
这里是我问题的核心
Bitmap Buffer; //this is initialized elsewhere, don't worry
public void MapPlotPanel_Paint(object sender, PaintEventArgs e)
{
//... Drawing code removed, it's just a novel Graphics object drawing into the Bitmap ...
e.Graphics.DrawImage(Buffer, Point.Empty);
}
虽然这可以将图像很好地绘制到面板中,但我会出现可怕的闪烁,因为我可以实时看到位图被绘制到面板中。即使我 Panel.CreateGraphics() 在事件处理程序中使用它而不是 PaintEventArgs 对象,就像我之前所做的那样,同样的事情也会发生。
在表单加载事件处理程序中,我有
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
没有效果。
不过,最糟糕的是,如果我不使用 Graphics 将图像应用于面板,而是 Panel.BackgroundImage = Buffer,它永远不会闪烁,当然,绘制的内容只会显示下一个组件失效的时间。
我真的想不出我在这里可能遗漏了什么,我们将不胜感激。
正如评论中已经提到的那样 - 要启用面板的双缓冲,您需要 SetStyle()
在面板构造函数中,而不是在表单加载事件中。为此,您必须创建自己的面板。下面是自定义面板的示例代码 class.
public partial class CustomPanel : UserControl
{
public CustomPanel()
{
InitializeComponent();
// Add Double Buffering
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
}
}
目前正在重写旧代码,其中我使用图形函数绘制基于位置数据的交互式矢量地图。
回到使用 .NET 4.7 时,我可以简单地将我的东西绘制到位图中,执行 Graphics gr = Panel.CreateGraphics(),然后执行 gr.DrawImage()。我从来没有启用双缓冲,而且它总是工作正常。
现在我在 .NET 5 中,仍然使用 WinForms,并尝试根据 Paint 事件做一些更好的事情,并在与之交互时使组件无效。
这里是我问题的核心
Bitmap Buffer; //this is initialized elsewhere, don't worry
public void MapPlotPanel_Paint(object sender, PaintEventArgs e)
{
//... Drawing code removed, it's just a novel Graphics object drawing into the Bitmap ...
e.Graphics.DrawImage(Buffer, Point.Empty);
}
虽然这可以将图像很好地绘制到面板中,但我会出现可怕的闪烁,因为我可以实时看到位图被绘制到面板中。即使我 Panel.CreateGraphics() 在事件处理程序中使用它而不是 PaintEventArgs 对象,就像我之前所做的那样,同样的事情也会发生。
在表单加载事件处理程序中,我有
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
没有效果。
不过,最糟糕的是,如果我不使用 Graphics 将图像应用于面板,而是 Panel.BackgroundImage = Buffer,它永远不会闪烁,当然,绘制的内容只会显示下一个组件失效的时间。
我真的想不出我在这里可能遗漏了什么,我们将不胜感激。
正如评论中已经提到的那样 - 要启用面板的双缓冲,您需要 SetStyle()
在面板构造函数中,而不是在表单加载事件中。为此,您必须创建自己的面板。下面是自定义面板的示例代码 class.
public partial class CustomPanel : UserControl
{
public CustomPanel()
{
InitializeComponent();
// Add Double Buffering
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
}
}