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 ...
随机推荐
- Django QuerySet 进阶
QuerySet 进阶 阅读本文你可以学习到什么 1. 查看 Django queryset 执行的 SQL(1部分) 2. 获得的查询结果直接以类似list方式展示(2,3 部分) 3. 如何在dj ...
- poj3415(后缀数组)
poj3415 题意 给定两个字符串,给出长度 \(m\) ,问这两个字符串有多少对长度大于等于 \(m\) 且完全相同的子串. 分析 首先连接两个字符串 A B,中间用一个特殊符号分割开. 按照 \ ...
- 拓扑排序【p1137】 旅行计划
Description 小明要去一个国家旅游.这个国家有\(N\)个城市,编号为\(1\)至\(N\),并且有\(M\)条道路连接着,小明准备从其中一个城市出发,并只往东走到城市\(i\)停止. 所以 ...
- 一个错误使用单例模式的场景及ThreadLocal简析
近来参与一个Java的web办公系统,碰到一个bug,开始猜测是线程池管理的问题,最后发现是单例模式的问题. 即,当同时发起两个事务请求时,当一个事务完成后,另一个事务会抛出session is cl ...
- Maximum Product of Word Lengths -- LeetCode
Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the tw ...
- C++指针、引用知多少?
上午搞了一个小程序,test半天都没有得到想要的结构,原来是递归的时候没有注意的循环的问题,结果直接死循环了.催了...看来当程序出现问题的时候,首先要整理的是算法思路是否有问题,其次是算法的实现,是 ...
- redis 安装并且设置开机后台自动启动(转)
1,安装redis wget http://download.redis.io/releases/redis-2.8.8.tar.gz .tar.gz cd redis- make 2,建立Red ...
- 浅谈Java中静态初始化块跟非初始化块
众所周知在JAVA编程语言中有两种初始化块: 静态初始化块 非静态初始化块 他们到底有什么区别呢?今天就浅谈一下JAVA中静态初始化块和非静态初始化块的区别 静态初始化块 定义: ...
- Makefile学习之显示命令与出错命令
显示命令: 1.在makefile中 如果在命令行下添加“@”符号,则只执行,不显示命令: 2.在执行make时,make -n 表示只显示命令而不执行: make -s 表示只执行命令而不显示: 3 ...
- mapbox 接入高德矢量地图实战
Mapbox 作为现如今比较流行的地图框架为我们提供了漂亮的个性化地图,在平常的使用过程中可以方便的接入高德/谷歌等矢量切片地图.由于Mapbox地图数据来源于Open Street Map等国外厂商 ...