一、问题:解决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的并发并行[2] -> 队列[1] -> 使用队列进行任务控制

    使用队列进行任务控制 1 FIFO与LIFO队列 FIFO(First In First Out)与LIFO(Last In First Out)分别是两种队列形式,在FIFO中,满足先入先出的队列方 ...

  2. #420 Div2 C

    #420 Div2 C 题意 不断把数加入到一个栈里,取数的时候要求按照 1~n 的顺序取数,每次取数保证数一定在栈里,如果要取的数不在栈头,可以选择对栈排序一次.问最少排序几次. 分析 只要栈头的数 ...

  3. 拓扑排序+数学+DP【p1685】游览

    Description 顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了! 你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开.可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!!于是 ...

  4. js部分的总结

    一.词法结构 1.区分大小写 2.注意//单行/*多行注释* 3.字面量(直接量 literal) 12 //数字 5.8 //小数 “hello” ‘hello’ true /js/gi  //正则 ...

  5. ORACLE查询当前连接的用户信息及操作的SQL语句

    ORACLE--查询当前连接的用户信息及操作的SQL语句    select sid,      status,      v$session.username 用户名,      last_call ...

  6. 安装php5.4.10时, 错误:‘gdIOCtx’ 没有名为 ‘data’ 的成员

    安装php5.4.10时, 错误:‘gdIOCtx’ 没有名为 ‘data’ 的成员 在安装php时,报如下错误 In file included from /kk/php-5.4.0/ext/gd/ ...

  7. 为Chrome多账户添加单独的快捷方式

    Chrome的多账户功能非常好用,每个账户都有自己的独立的收藏夹.个人设置等.但是,当你要使用的账户不是默认账户时,必须经过一个切换的操作.本文将简单的介绍一个如何各账户添加快捷方式,从而实现直接登陆 ...

  8. Visual Studio Package扩展——vsct文件简介

    首先我们使用向导生成一个package的扩展,里面就会发现一个vsct文件.vsct文件的全称是Visual Studio Command Table,它其实就是一个xml文件,通过一定的规则来描述v ...

  9. Http协议三次握手过程

    Http协议三次握手过程   TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: ...

  10. CSS从大图片上截取小图标

    一张图片,用CSS分割成多个小图标. css样式: .icon{ background:url(../images/tabicons.png) no-repeat;width:18px; line-h ...