Winform 动态 画图 不闪
一、问题:解决winform动态画图闪的问题,网上搜的方法,大部分都是:
- “this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);”,甚至直接“this.DoubleBuffered = true;”。
- 先 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 动态 画图 不闪的更多相关文章
- Android SurfaceView实现静态于动态画图效果
本文是基于Android的SurfaceView的动态画图效果,实现静态和动态下的正弦波画图,可作为自己做图的简单参考,废话不多说,先上图, 静态效果: 动态效果: 比较简单,代码注释的也比较详细,易 ...
- WinForm动态查询
WinForm 动态查询 1. 使用场景 在对数据进行筛选, 包含多个筛选字段时适用. 2. 接口设计 /// <summary> /// 定义可作为追加到 WHERE 子句的控件接口 / ...
- C# WinForm动态添加MSChart控件
添加mschart.dll动态链接库 添加引用 System.Windows.Forms.DataVisualization MSChart控件作为方便的用户数据展示控件,可以方便的使用控件提 ...
- c# winform动态生成控件与获取动态控件输入的值
差不多有2年没有写winform程序,一直都是写bs.最近项目需要,又开始着手写一个小功能的winform程序,需要动态获取xml文件的节点个数,生成跟节点个数一样的textbox, 最后还要获取操作 ...
- plt实现动态画图
用pycharm跑的没有出现动态线条的话: 1.点击setting,输入关键字Scien...搜索出Python Scientific, 在右侧去掉对勾(默认是勾选的),然后右下角Apply--OK, ...
- [C#]WinForm动态删除控件 Controls.Remove()
今天遇到一个奇怪的问题,在WinForm内动态添加Button后再动态的移除,发生稀奇古怪的现象,Button控件只被规律的移除,没有完全移除 foreach (Control c in this.C ...
- C#在透明窗体WinForm上面画图(电子尺小工具的实现)
前几天要做一个微信调一调的外挂,里面用到了尺子测量距离,然后就自己下载了一个电子尺,最近要升级我的跳一跳外挂,然后就准备自己做一个电子尺,嵌入到我的外挂里面,在嵌入到我的外挂之前,我自己做了一个完整版 ...
- winform 添加背景图 闪屏问题解决
winform中只要添加了背景图片资源,窗体加载显示的时候就会出现不停的闪屏操作,网上找了很多方法,效果都不明显: 然后自己观察和思路:看窗体的加载过程,当有背景图的时候,首先出来的是背景图,之后背景 ...
- 如何:在 Winform 动态启动、控制台命令行?
需求 winForm 程序输出类型为 windows 程序(不是命令行程序) 在运行时想输入一些信息编译开发调试,如何实现这一功能 解答: AllocConsole.FreeConsole ...
随机推荐
- CentOS 7.0 服务管理 – systemctl 命令
转载自:http://linux.it.net.cn/CentOS/fast/2014/0720/3212.html CentOS 7.0中已经没有service命令,而是启用了systemctl服务 ...
- 【分享】· 图床&在线分享演示文稿
关于图床 什么是图床? 这并不是一个多么高大上的名词概念!用比较通俗的话来说,当你在撰写新文章时,你需要去插入图片以使得你的文章内容更加直观.易懂,这个时候有以下几种办法: 在博客根目录的 sourc ...
- centos下crontab的使用
1.作用 使用crontab命令可以修改crontab配置文件,然后该配置由cron公用程序在适当的时间执行,该命令使用权限是所有用户. 2.格式 crontab [-u user] {-l | -r ...
- CSS3快速浏览器前缀的方法
在做前端开发时,经常要在css3的属性前加上各浏览器厂商的前缀:,如 Chrome(谷歌浏览器) :-webkit- Safari(苹果浏览器) :-webkit- Firefox(火狐浏览器) :- ...
- DNX 概览
来源https://docs.asp.net/en/latest/dnx/overview.html .NET Execution Environment是什么 .NET Execution Envi ...
- django admin后台编辑页面 显示数据公式
先用django markdownx进行实时预览, 然后在 /Library/Python/2.7/site-packages/django/contrib/admin 这个目录下,加入 <sc ...
- 用curl获取https请求时出现错误的处理
今天一个同事反映,使用curl发起https请求的时候报错:“SSL certificate problem, verify that the CA cert is OK. Details: erro ...
- Git 历险记(三)——创建一个自己的本地仓库
如果我们要把一个项目加入到Git的版本管理中,可以在项目所在的目录用git init命令建立一个空的本地仓库,然后再用git add命令把它们都加入到Git本地仓库的暂存区(stage or inde ...
- jquery 获取table当前行值
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- [Functional Programming] Define Discrete State Transitions using the State ADT
We build our first state transactions as two discrete transactions, each working on a specific porti ...