上几张测试的 效果

虽然全是用.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. oracle decode 用法

    含义解释: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译值1)ELSIF 条件=值2 THEN ...

  2. Spring AspectJ AOP 完整示例

    http://outofmemory.cn/java/spring/AOP/aop-aspectj-example-before-after-AfterReturning-afterThrowing- ...

  3. Java之线程池(二)

    关于线程和线程池的学习,我们可以从以下几个方面入手: 第一,什么是线程,线程和进程的区别是什么 第二,线程中的基本概念,线程的生命周期 第三,单线程和多线程 第四,线程池的原理解析 第五,常见的几种线 ...

  4. linux 11 -- mount,umount

    Linux 文件系统是一个以 / 为根的大树,我们在不同的设备和分区上都有文件系统.我们如何处理这种明显的不一致性?根 (/) 文件系统是在初始化过程中挂载的.您创建的其他每个文件系统在挂载 在挂载点 ...

  5. mysql用户和权限管理(Linux系统下)

    在mysql自带的库中有一个mysql,这个库包含了太多的东西,其中有一张表user,这张表存储了所有的用户信息. mysql> select user,host,password from u ...

  6. NSAttributedStringKey

    NSFontAttributeName; //字体,value是UIFont对象 NSParagraphStyleAttributeName;//绘图的风格(居中,换行模式,间距等诸多风格),valu ...

  7. shiro3

    1 shiro介绍 1.1 什么是shiro shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证.用户授权. spring中有spring security (原名Acegi ...

  8. Python 案例一(计算人体体脂率)

    #计算人体体脂率 #输入部分 #身高 personHeight = input("请输入你的身高(m):") personHeight = float(personHeight) ...

  9. 关于 tornado.simple_httpclient SimpleAsyncHTTPClient fetch下载大文件,默认60s的问题

    遇到了线上发布任务失败的情况,要发布的包大小77M,网络OK,手动测试速度是1.7M,下载77M文件用时17s左右,理论上完全没有问题 但是,从日志看确实是download的时候,60s 超时了,而且 ...

  10. Codeforces 158E Phone Talks:dp

    题目链接:http://codeforces.com/problemset/problem/158/E 题意: 你有n个电话要接,每个电话打进来的时刻为第t[i]分钟,时长为d[i]分钟. 每一个电话 ...