上几张测试的 效果

虽然全是用.net 的绘图库画的,但是手动双缓冲,不会闪烁,感觉还不错,源码开放了,喜欢的拿去扩展吧;

用于撤销的存放图像的数据结构我设置为10个,怕是内存崩了,我看mspaint的内存占用一直很低啊,如有有比较棒的解决方案的话欢迎提出来分享分享

代码量短短300行





【2016.1.27】更新一下博文,因为扩展了一下,因为撤销功能放内存中实在是太耗资源了,我重新实现一种数据结构,这种数据结构同时兼容栈和队列的功能,栈大小固定,

压栈时会溢出,溢出的话从栈底抽走元素并返回,这样就可以在使用数据结构是把溢出的bitmap放到磁盘上

弹栈时如果有之前溢出的bitmap的话向栈底插入元素,把磁盘上的bitmap向栈底插入

这样的话控件既节省内存也不会因为磁盘的IO速度影响撤销功能导致界面卡顿

下面是这个数据结构的实现代码,为了节省代码,我不做成泛型了

 //_____________________________________________________________________________

        /*下面的stack and queue类是
         *
         * 一个兼容栈和队列的数据结构
         * 为了节省代码量,我没有设计成泛型
         * 设计这个数据结构为了节省空间在保留内存
         * 把纪录画纸保存在系统的临时目录下
         *
         *
         *
         * */
        /// <summary>
        /// 栈元素类
        /// </summary>
        internal class TElement
        {
            public TElement prev;
            public Bitmap i;
            public TElement next;

            internal TElement(TElement prev, Bitmap i, TElement next)
            {
                this.i = (Bitmap)i.Clone();
                this.prev = prev;
                this.next = next;
            }

        }

        internal class stack_and_queue
        {
            internal int size;
            ;
            ;
            private TElement head = null;
            private TElement tail = null;
            public stack_and_queue(int size)
            {
                ) size = ;
                this.size = size;
            }

            /// <summary>
            /// 压栈画纸
            /// </summary>
            /// <param name="x"></param>
            /// <returns></returns>
            public Bitmap Push(Bitmap x)
            {
                if (x == null) return null;
                TElement t = new TElement(tail, x, null);
                if (head == null)
                {
                    head = t;
                    tail = t;
                    allcount++;
                    count++;
                    return null;
                }
                else
                {
                    tail.next = t;
                    tail = t;
                    allcount++;
                    count++;
                    if (allcount > size)
                    {

                        Bitmap temp = head.i;
                        head.next.prev = null;
                        head = head.next;
                        count--;
                        return temp;
                    }
                }
                return null;
            }

            /// <summary>
            /// 弹栈画纸
            /// </summary>
            /// <param name="t"></param>
            /// <returns></returns>
            public Bitmap Pop(Bitmap t)
            {
                if (tail == null) return null;
                Bitmap temp = tail.i;
                if (head == tail)
                {
                    head = tail = null;
                    allcount--;
                    count--;
                }
                else
                {
                    tail = tail.prev;
                    tail.next = null;
                    allcount--;
                    count--;
                    if (t != null)
                    {
                        TElement tnew = new TElement(null, t, head);
                        head.prev = tnew;
                        head = tnew;
                        count++;
                    }
                }
                return temp;
            }

            /// <summary>
            /// 清空栈
            /// </summary>
            internal void clear()
            {
                TElement temp = head;
                while (temp != null)
                {
                    temp = head.next;
                    head.prev = null;
                    head.next = null;
                    head.i.Dispose();
                }
                head = null;
                tail = null;
            }
        }

这个是没有使用stack_and_queue数据结构实现撤销功能的控件的内存占用


下面这个是使用stack_and_queue数据结构的,在画的多的情况下内存占用依然比较低,栈的大小我设置为3

注明一下:

【里面的一个 把bitmap加载到内存,保证不占用文件的FileToBitmap方法的代码我是copy别人的

原帖地址http://blog.csdn.net/rztyfx/article/details/46674543

源码地址:http://pan.baidu.com/s/1eRwcflw

cs文件是控件源码

压缩文件是测试控件的demo文件

C#自定义控件 绘制框的更多相关文章

  1. (十六)c#Winform自定义控件-文本框哪里去了?-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  2. (六)c#Winform自定义控件-单选框

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  3. (二十八)c#Winform自定义控件-文本框(一)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  4. (二十九)c#Winform自定义控件-文本框(二)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  5. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  6. (三十一)c#Winform自定义控件-文本框(四)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  7. (十八)c#Winform自定义控件-提示框

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  8. (八十二)c#Winform自定义控件-穿梭框

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  9. c# 自定义控件-提示框(弹框)

    分带取消按钮和不带取消按钮的 调用方法: frmMessageBox frm = new frmMessageBox("提示", "数据连接失败,请重试!", ...

随机推荐

  1. ADT和Android SDK的安装

    本文主要涉及Android开发环境搭建时的Eclipse.ADT及Android SDK的安装方法,还有遇到的两个问题及其解决办法.其中,ADT的安装介绍了在线和离线安装两种方式.  1.安装ecli ...

  2. Linux基础系列:常用命令(5)_samba服务与nginx服务

    作业一:部署samba 每个用户有自己的目录,可以浏览内容,也可以删除 所有的用户共享一个目录,只能浏览内容,不能删 安装samba服务 1.准备环境 setenforce 0 2.安装软件包 yum ...

  3. 扣出thinkphp数据库操作类

    假如你是一位thinkphp的使用者,想必你会觉得thinkphp操作数据库非常方便.现在在你面前有一个非常小的作业,小到完全没有必要用thinkphp去完成它.但是你又觉得不用thinkphp的话, ...

  4. 3.25课·········JavaScript的DOM操作

    1.DOM的基本概念 DOM是文档对象模型,这种模型为树模型:文档是指标签文档:对象是指文档中每个元素:模型是指抽象化的东西. 2.Window对象操作 一.属性和方法: 属性(值或者子对象): op ...

  5. 【leetcode刷题笔记】3Sum Closest

    Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...

  6. python中自定义排序函数

    Python内置的 sorted()函数可对list进行排序: >>>sorted([36, 5, 12, 9, 21]) [5, 9, 12, 21, 36] 但 sorted() ...

  7. Excel 2007中自定义数字格式前要了解的准则

    要在Excel 2007中创建自定义数字格式,首先应了解自定义数字格式的准则,并从选择某一内置数字格式开始.然后,可以更改该格式的任意代码部分,从而创建自己的自定义数字格式. 数字格式最多可包含四个代 ...

  8. String类型的对象,是保存在堆里还是在栈里呢?

    在Java的实现中,new出来的String对象一般是放在堆中的. 如果是 String s ="xxx"; 这种,那就是放在常量池中. JDK6将常量池放在方法区中. 方法区此时 ...

  9. DIV+CSS专题:第一天 XHTML CSS基础知识

    欢迎大家学习<十天学会web标准>,也就是我们常说的DIV+CSS.不过这里的DIV+CSS是一种错误的叫法,建议大家还是称之为web标准.   学习本系列教程需有一定html和css基础 ...

  10. POJ 2831 Can We Build This One:次小生成树【N^2预处理】

    题目链接:http://poj.org/problem?id=2831 题意: 给你一个图,每条边有边权. 然后有q组询问(i,x),问你如果将第i条边的边权改为x,这条边是否有可能在新的最小生成树中 ...