Sea*_*son 3 c# refresh panel flicker background-image
我有一个填写父表格的小组.
我使用Timer来捕获屏幕,
并将屏幕截图设置为Panel的背景图像.
然而,它会遇到疯狂的闪烁.我该怎么做才能解决它?
//Part of code
public partial class Form1 : Form
{
DxScreenCapture sc = new DxScreenCapture();
public Form1()
{
InitializeComponent();
panelMain.BackgroundImageLayout = ImageLayout.Zoom;
}
private void Form1_Load(object sender, EventArgs e)
{
}
void RefreshScreen()
{
Surface s = sc.CaptureScreen();
DataStream ds = Surface.ToStream(s, ImageFileFormat.Bmp);
panelMain.BackgroundImage = Image.FromStream(ds);
s.Dispose();
}
private void timer1_Tick(object sender, EventArgs e)
{
RefreshScreen();
}
}
Run Code Online (Sandbox Code Playgroud)
尝试使用双缓冲面板.继承面板,将DoubleBuffered设置为true并使用该面板而不是默认面板:
namespace XXX
{
/// <summary>
/// A panel which redraws its surface using a secondary buffer to reduce or prevent flicker.
/// </summary>
public class PanelDoubleBuffered : System.Windows.Forms.Panel
{
public PanelDoubleBuffered()
: base()
{
this.DoubleBuffered = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
另外,我想鼓励您更多地关注您使用的资源.每当一个对象实现IDisposable接口时 - 在不再需要时处置该对象.在处理非托管资源(例如流)时,这非常重要!
void RefreshScreen()
{
using (Surface s = sc.CaptureScreen())
{
using (DataStream ds = Surface.ToStream(s, ImageFileFormat.Bmp))
{
Image oldBgImage = panelMain.BackgroundImage;
panelMain.BackgroundImage = Image.FromStream(ds);
if (oldBgImage != null)
oldBgImage.Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我自己从其他网站找到了答案。它在面板上设置一些ControlStyle,如下代码所示。并且不再闪烁。
class SomePanel : Panel
{
public SomePanel()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.UserPaint, true);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
实际上,Visual Studio 中有一个更简单的解决方案,无需任何代码!
如果您转到“解决方案资源管理器”,然后双击您的表单(Form1),将会弹出一个列表(如果没有弹出,您只需右键单击您的表单并转到“属性”并再次双击)。然后,转到DoubleBuffered并将其更改为True。