C#自定义控件 绘制框
上几张测试的 效果


虽然全是用.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#自定义控件 绘制框的更多相关文章
- (十六)c#Winform自定义控件-文本框哪里去了?-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
- (六)c#Winform自定义控件-单选框
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (二十八)c#Winform自定义控件-文本框(一)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (二十九)c#Winform自定义控件-文本框(二)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (三十)c#Winform自定义控件-文本框(三)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (三十一)c#Winform自定义控件-文本框(四)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (十八)c#Winform自定义控件-提示框
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (八十二)c#Winform自定义控件-穿梭框
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- c# 自定义控件-提示框(弹框)
分带取消按钮和不带取消按钮的 调用方法: frmMessageBox frm = new frmMessageBox("提示", "数据连接失败,请重试!", ...
随机推荐
- ADT和Android SDK的安装
本文主要涉及Android开发环境搭建时的Eclipse.ADT及Android SDK的安装方法,还有遇到的两个问题及其解决办法.其中,ADT的安装介绍了在线和离线安装两种方式. 1.安装ecli ...
- Linux基础系列:常用命令(5)_samba服务与nginx服务
作业一:部署samba 每个用户有自己的目录,可以浏览内容,也可以删除 所有的用户共享一个目录,只能浏览内容,不能删 安装samba服务 1.准备环境 setenforce 0 2.安装软件包 yum ...
- 扣出thinkphp数据库操作类
假如你是一位thinkphp的使用者,想必你会觉得thinkphp操作数据库非常方便.现在在你面前有一个非常小的作业,小到完全没有必要用thinkphp去完成它.但是你又觉得不用thinkphp的话, ...
- 3.25课·········JavaScript的DOM操作
1.DOM的基本概念 DOM是文档对象模型,这种模型为树模型:文档是指标签文档:对象是指文档中每个元素:模型是指抽象化的东西. 2.Window对象操作 一.属性和方法: 属性(值或者子对象): op ...
- 【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 ...
- python中自定义排序函数
Python内置的 sorted()函数可对list进行排序: >>>sorted([36, 5, 12, 9, 21]) [5, 9, 12, 21, 36] 但 sorted() ...
- Excel 2007中自定义数字格式前要了解的准则
要在Excel 2007中创建自定义数字格式,首先应了解自定义数字格式的准则,并从选择某一内置数字格式开始.然后,可以更改该格式的任意代码部分,从而创建自己的自定义数字格式. 数字格式最多可包含四个代 ...
- String类型的对象,是保存在堆里还是在栈里呢?
在Java的实现中,new出来的String对象一般是放在堆中的. 如果是 String s ="xxx"; 这种,那就是放在常量池中. JDK6将常量池放在方法区中. 方法区此时 ...
- DIV+CSS专题:第一天 XHTML CSS基础知识
欢迎大家学习<十天学会web标准>,也就是我们常说的DIV+CSS.不过这里的DIV+CSS是一种错误的叫法,建议大家还是称之为web标准. 学习本系列教程需有一定html和css基础 ...
- POJ 2831 Can We Build This One:次小生成树【N^2预处理】
题目链接:http://poj.org/problem?id=2831 题意: 给你一个图,每条边有边权. 然后有q组询问(i,x),问你如果将第i条边的边权改为x,这条边是否有可能在新的最小生成树中 ...