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("提示", "数据连接失败,请重试!", ...
随机推荐
- IE11 for Windows 7 Enterprise With SP1 故障
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jaminwm/article/details/29592027 这个故障非常诡异,卸载IE11也没实 ...
- python3的时间日期处理
1.python3日期和时间 Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能. Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间. 时 ...
- ppm图像相关
PPM图像格式介绍 直接拿具体的数据来说明是最直接的,使用ue打开ppm文件,采用的都是十六进制asc码表示的,这里要注意地址00000000h中的最后一个字母是始终不变的,这原来没注意晕了我好久,第 ...
- Ubuntu安装教程
http://www.linuxdiyf.com/linux/13198.html 简易配置说明 磁盘分区,新分区的磁盘必须是未分配的, 到管理-磁盘管理下面查看磁盘是不是未分配的,如果已分配了,在磁 ...
- CSS选择器(一)
一.CSS 元素选择器 最常见的 CSS 选择器是元素选择器.换句话说,文档的元素就是最基本的选择器. 如果设置 HTML 的样式,选择器通常将是某个 HTML 元素,比如 p.h1.em.a,甚至可 ...
- AJAX请求时status返回状态明细表
AJAX请求时status返回状态明细表 readyState的五种状态2010-03-04 18:24对于readyState的五种状态的描述或者说定义,很多Ajax书(英文原版)中大都语焉不详 在 ...
- Python 注释和中文乱码
Python 注释分为三种: 1.单行注释:# 2.多行注释:前后3个单引号,或者三个双引号: 如:''' 多行注释 ''', """或者 多行注释 '"&qu ...
- SrpingCloud 之SrpingCloud config分布式配置中心
Config架构 当一个系统中的配置文件发生改变的时候,我们需要重新启动该服务,才能使得新的配置文件生效,spring cloud config可以实现微服务中的所有系统的配置文件的统一管理,而且还可 ...
- Entity Framework在Asp.net MVC中的实现One Context Per Request(转)
上篇中"Entity Framework中的Identity map和Unit of Work模式", 由于EF中的Identity map和Unit of Work模式,EF体现 ...
- 各种IoC框架下实现AOP
.Net AOP(五) 各种IoC框架下实现AOP 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率 主要功能 日志记录,性 ...