在调整大小时将图像绘制到Panel控件上会产生伪像

Uwe*_*eim 7 c# drawing onpaint winforms

目前我正在尝试做我认为简单的任务:

Panel在Windows窗体中将图像绘制到控件的整个区域.(请忽略我可以使用该BackgroundImage物业的那一刻)

要绘制的图像如下所示:

在此输入图像描述

即一个黄色的盒子,周围有一个1像素的蓝色框架.

要绘制,我正在使用控件的Paint事件Panel:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawImage(Resources.MyImage, panel1.ClientRectangle);
}
Run Code Online (Sandbox Code Playgroud)

这在最初显示表单时看起来很好:

在此输入图像描述

调整窗体大小(以及对接面板)时,要么在缩小时缩小边缘...

在此输入图像描述

...或者当它变得更大时它会绘制人工制品:

在此输入图像描述

我很确定会有一些相当简单和直接的东西,但我真的无法理解其中的原因.

由于我忽略了ClipRectangle并总是画出一切,我认为图像会一直缩放.

我的问题是:

  • 这些文物的原因是什么?(我喜欢明白这一点!)
  • 为了摆脱人工制品,我该怎么做?(旁边调用Invalidate每个调整大小)

更新,解决方案:

感谢Ryan的回答,我找到了一个可以接受的解决方案.基本上我衍生自类Panel,做过的重写OnPaintBackground,也没有调用基方法.最后,我将以下代码添加到派生面板的构造函数中:

base.DoubleBuffered = true;

SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

UpdateStyles();
Run Code Online (Sandbox Code Playgroud)

Ry-*_*Ry- 5

出现伪影的原因是,在调整表单大小时不会重绘整个表面。只有必要的部分。通常最好的解决方案是您不希望执行的操作,调用Invalidate每个调整大小。但是,如果实际上这是您的情况,请改用a PictureBox。如果不是这样,您可以考虑OnPaint改用表单覆盖,并使用它this.SetStyle(ControlStyles.ResizeRedraw, true)来自动执行此操作。

  • @UweKeim:您需要启用双缓冲;子类“ Panel”,使用“ OnPaint”代替“ Paint”处理,并将“ DoubleBuffered”属性设置为“ true”。 (2认同)