吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3427|回复: 4
收起左侧

[其他原创] Winform 动态 画图 不闪

[复制链接]
andrea225 发表于 2018-3-21 22:58
本帖最后由 andrea225 于 2018-3-22 15:42 编辑

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

  •   “this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);”,甚至直接“this.DoubleBuffered = true;”。
  •   先 new 个Bitmap,画在Bitmap上,然后再把Bitmap画在界面上。
  凡是直接这么给人解答问题的,基本都是属于道听途说,自己没试过的。或者根本就没注意要解决的是“动态”的问题。

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

  

  三、代码:简单封了个自定义控件,用Action传入画图方法:
[C#] 纯文本查看 复制代码
// --------------------------------------------------------------------------------------------------------------------
// <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” 来画。
  四、调用的方式如下:
[C#] 纯文本查看 复制代码
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 > 1).ToList();
            if (this.lines.Count > 0)
            {
                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, 2);
                    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; }
    }
}

5ab35dd2f2ccf_5ab35dd374ce1.gif

免费评分

参与人数 1吾爱币 +2 热心值 +1 收起 理由
wushaominkk + 2 + 1 鼓励新人发帖,吾爱因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wushaominkk 发表于 2018-3-22 10:01
鼓励新人发帖,吾爱因你更精彩!
peterq521 发表于 2018-3-22 10:05
楼主能否做一个简易的成品工具 方便一键操作多谢
认定666 发表于 2018-3-22 10:38
效果图一直看不了,我换了几个浏览器了,都还是刷不出,是不是楼主放图片的时候上传出了什么故障呀?
一开始我还以为是我Chrome的加载Flash插件的问题,后来查了一下,没有问题呀,也换了几个浏览器试了,也是刷不出图片。
会不会是运营商劫持或者其他原因。
 楼主| andrea225 发表于 2018-3-22 15:43
认定666 发表于 2018-3-22 10:38
效果图一直看不了,我换了几个浏览器了,都还是刷不出,是不是楼主放图片的时候上传出了什么故障呀?
一开 ...

修复了,不好意思,原来图片是上传到博客园的,可能被屏蔽了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 13:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表