1,问题描述:
- 在winform中使用Graphics进行绘图,绘图效果却呈现异常闪烁。
2,解决办法:
- 使用 SetStyle() 设置相应特性:
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
this.SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
- 建立临时对象,在临时对象上绘制完成后再一次性赋值给控件。
Bitmap map = new Bitmap(panel1.Width, panel1.Height);using (Graphics g = Graphics.FromImage(map)){g.Clear(SystemColors.Control);g.FillPie(Brushes.SlateBlue, rec, 0, 360 - availDegree);//计算字符串插入位置坐标double degree = ((360 - availDegree) / 180 * Math.PI) / 2;Point center = new Point(rec.X + panel1.Width / 2, rec.Y + panel1.Height / 2);PointF p1 = new PointF((float)(center.X + Math.Cos(degree) * (min / 2)), (float)(center.Y + Math.Sin(degree) * (min / 2)));g.DrawString($"已使用:{Math.Round((1 - pc.AvailablePhysicalMemory * 1.0 / pc.TotalPhysicalMemory) * 100, 2, MidpointRounding.AwayFromZero)}%", new Font("微软雅黑", 8, FontStyle.Bold), Brushes.Red, new Point(10, 10));g.FillPie(Brushes.Green, rec, 360 - availDegree, availDegree);}panel1.BackgroundImage = map;
3,注意点:
protected void SetStyle(ControlStyles flag, bool value);
该方法属于protected类型位于Control类中,即只能在Control类中被调用或者在继承自Control的子类中被调用。
所以在继承自Control的类Form1中可以被直接调用:
this.SetStyle(ControlStyles.UserPaint, true);this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.this.SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
但是如果想将其应用于Form1类中定义的panel01对象则必须通过反射进行设置。
//因为该方法是保护类型protect 只能在自己类或者其继承类中调用,所以这里用反射System.Reflection.MethodInfo method = typeof(Panel).GetMethod("SetStyle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);method.Invoke(panel1, new object[] { ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.UserPaint, true });
亦或是在派生自Panel的类型中进行设置。
class CustomPanel:Panel{public CustomPanel(){this.SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);}}