一、问题:解决winform动态画图闪的问题,网上搜的方法,大部分都是:

  1. “this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);”,甚至直接“this.DoubleBuffered = true;”。
  2. 先 new 个Bitmap,画在Bitmap上,然后再把Bitmap画在界面上。

  凡是直接这么给人解答问题的,基本都是属于道听途说,自己没试过的。或者根本就没注意要解决的是“动态”的问题。

  二、解决方法:动态画图不闪的方法如下,先上效果图(请忽略鼠标样式,是gif录制软件的效果):

  

  三、代码:简单封了个自定义控件,用Action传入画图方法:

 // --------------------------------------------------------------------------------------------------------------------
// <copyright file="PictureBoxEx.cs" company="hyl">
// hyl
// </copyright>
// <summary>
// 用Action传画图方法。不闪。
// </summary>
// -------------------------------------------------------------------------------------------------------------------- namespace HYL
{
using System;
using System.Drawing;
using System.Windows.Forms; public partial class PictureBoxEx : PictureBox
{
/// <summary>
/// 画图方法
/// </summary>
private Action<Graphics> draw; public PictureBoxEx()
{
this.InitializeComponent(); // 开双缓存(用这种方法,画图不太复杂的话,甚至不开也不闪。。。)
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
} public void Rander(Action<Graphics> Draw)
{
this.Invalidate();
this.draw = Draw;
} protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe); // 画图
this.draw?.Invoke(pe.Graphics);
}
}
}

  重点在于要在 “OnPaint” 执行画图代码,也就是说要用 “OnPaint” 里的 “pe.Graphics” 来画。

  四、调用的方式如下:

 namespace HYL
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms; public partial class Form1 : Form
{
List<Line> lines = new List<Line>(); private bool painting; public Form1()
{
this.InitializeComponent();
} private void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// 左键确定点
if (this.btnLine.Checked)
{
this.lines.Last().Points.Add(new LinePoint { IsTemp = false, Point = e.Location });
this.painting = true;
}
} if (e.Button == MouseButtons.Right)
{
// 右键停止画图
if (this.btnLine.Checked)
{
this.ClearEmptyLines();
} this.painting = false;
this.btnLine.Checked = false;
}
} private void ClearEmptyLines()
{
this.lines = this.lines.Where(l => l.Points.Count > ).ToList();
if (this.lines.Count > )
{
var lastLine = this.lines.Last();
lastLine.ClearTempPoints();
}
} private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (this.painting)
{
if (this.btnLine.Checked)
{
this.PaintingLine(e);
} this.Draw();
}
} private void PaintingLine(MouseEventArgs e)
{
var lastLine = this.lines.Last();
var lastPoint = lastLine.Points.Last(); if (lastPoint.IsTemp)
{
lastLine.Points.Remove(lastPoint);
} LinePoint newPoint = new LinePoint { IsTemp = true, Point = e.Location };
lastLine.Points.Add(newPoint);
} /// <summary>
/// 画图
/// </summary>
private void Draw()
{
Action<Graphics> draw = g =>
{
Pen pen = new Pen(Color.Black, );
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; if (this.lines != null)
{
foreach (Line line in this.lines)
{
g.DrawLines(pen, line.GetPoints().ToArray());
}
}
}; this.pictureBoxEx1.Rander(draw);
} private void btnLine_CheckedChanged(object sender, EventArgs e)
{
if (this.btnLine.Checked)
{
this.lines.Add(new Line());
}
else
{
this.ClearEmptyLines();
this.painting = false;
this.Draw();
}
}
} public class Line : ShapeElement
{
public Line()
{
this.Points = new List<LinePoint>();
} // 线里的点
public IList<LinePoint> Points { get; set; } // 获取Point的集合
public IList<Point> GetPoints()
{
return this.Points.Select(p => p.Point).ToList();
} // 清理临时点
public void ClearTempPoints()
{
this.Points = this.Points.Where(p => !p.IsTemp).ToList();
}
} public class LinePoint
{
public Point Point { get; set; } // 是否临时点
public bool IsTemp { get; set; }
}
}

Winform 动态 画图 不闪的更多相关文章

  1. Android SurfaceView实现静态于动态画图效果

    本文是基于Android的SurfaceView的动态画图效果,实现静态和动态下的正弦波画图,可作为自己做图的简单参考,废话不多说,先上图, 静态效果: 动态效果: 比较简单,代码注释的也比较详细,易 ...

  2. WinForm动态查询

    WinForm 动态查询 1. 使用场景 在对数据进行筛选, 包含多个筛选字段时适用. 2. 接口设计 /// <summary> /// 定义可作为追加到 WHERE 子句的控件接口 / ...

  3. C# WinForm动态添加MSChart控件

    添加mschart.dll动态链接库 添加引用 System.Windows.Forms.DataVisualization     MSChart控件作为方便的用户数据展示控件,可以方便的使用控件提 ...

  4. c# winform动态生成控件与获取动态控件输入的值

    差不多有2年没有写winform程序,一直都是写bs.最近项目需要,又开始着手写一个小功能的winform程序,需要动态获取xml文件的节点个数,生成跟节点个数一样的textbox, 最后还要获取操作 ...

  5. plt实现动态画图

    用pycharm跑的没有出现动态线条的话: 1.点击setting,输入关键字Scien...搜索出Python Scientific, 在右侧去掉对勾(默认是勾选的),然后右下角Apply--OK, ...

  6. [C#]WinForm动态删除控件 Controls.Remove()

    今天遇到一个奇怪的问题,在WinForm内动态添加Button后再动态的移除,发生稀奇古怪的现象,Button控件只被规律的移除,没有完全移除 foreach (Control c in this.C ...

  7. C#在透明窗体WinForm上面画图(电子尺小工具的实现)

    前几天要做一个微信调一调的外挂,里面用到了尺子测量距离,然后就自己下载了一个电子尺,最近要升级我的跳一跳外挂,然后就准备自己做一个电子尺,嵌入到我的外挂里面,在嵌入到我的外挂之前,我自己做了一个完整版 ...

  8. winform 添加背景图 闪屏问题解决

    winform中只要添加了背景图片资源,窗体加载显示的时候就会出现不停的闪屏操作,网上找了很多方法,效果都不明显: 然后自己观察和思路:看窗体的加载过程,当有背景图的时候,首先出来的是背景图,之后背景 ...

  9. 如何:在 Winform 动态启动、控制台命令行?

    需求   winForm 程序输出类型为 windows 程序(不是命令行程序)   在运行时想输入一些信息编译开发调试,如何实现这一功能 解答:  AllocConsole.FreeConsole ...

随机推荐

  1. Python的功能模块[0] -> wmi -> 获取 Windows 内部信息

    wmi模块 / wmi Module WMI (Windows Management Instrumentation) 模块可用于获取 Windows 内部信息.该模块需要 win32com 的支持, ...

  2. 洛谷——P2640 神秘磁石

    P2640 神秘磁石 题目背景 在遥远的阿拉德大陆,有一种神秘的磁石,是由魔皇制作出来的, 题目描述 1.若给他一个一维坐标系,那么他的磁力一定要在素数坐标的位置上才能发挥的最大(不管位置坐标的大小, ...

  3. 1.13抽象类及接口(附简述final关键字)

    一.final final的中文意思就是不可更改的,最终的. 1.final修饰变量,那么该变量无法更改.一旦该变量赋了初值,就不能重新赋值. final MAX = 1100; //final修饰后 ...

  4. [CTF]Capture The Flag -- 夺旗赛

    CTF(Capture The Flag) 简单介绍 CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式. `In co ...

  5. JSP的内置对象(上)

    1.JSP内置对象的概念:JSP的内置对象时Web容器所创建的一组对象,不使用new关键字就可以使用的内置对象 2.JSP九大内置对象内置对象:out ,request ,response ,sess ...

  6. 阿里云ECS在CentOS 6.9中使用Nginx提示:nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)的解决方法

    说明: 1.[::]:80这个是IPv6的地址. 2.阿里云截至到今天还不支持IPv6. 解决方式: 1.普通解决方式:开启IPv6的支持,不过这个方法在阿里云行不通. vim /etc/nginx/ ...

  7. Makefile文件的使用

    编译程序: vi Makefile exe:a.c b.c gcc a.c b.c -o exe clean: rm exe 保存并退出: 这里exe:a.c b.c面的exe称为目标:a.c b.c ...

  8. ES6中的Map集合(与java里类似)

    Set类型可以用来处理列表中的值,但是不适用于处理键值对这样的信息结构.ES6也添加了Map集合来解决类似的问题 一.Map集合 JS的对象(Object),本质上是键值对的集合(Hash结构),但是 ...

  9. fabricjs 自定义类型

    https://stackoverflow.com/questions/36660108/how-to-create-custom-fabricjs-object I have to create a ...

  10. SpringMVC处理MYSQL BLOB字段的上传

    任务: uos.docfile的content字段是longblob类型的,通过页面将文件存储到这个字段里. 页面代码: <div class="box"> <d ...