小菜的系统框架界面设计-数据的完美呈现(DataGridView扩展)
背景
今天在做系统报表的过程中,我想实现批量操作DataGridView中的数据,在列中加复选框,通过一个事件触发进行全选或取消,可是在外面添加按钮,这种模式虽然能够实现,但是从系统界面设计的角度,美观和灵活性就差很多了,能否在DataGridView头标题栏上呈现复选框,通过这个头标题复选框来对这一列的复选框,这样是不是更灵活,也美观一点?
问题
可是,找了半天,发现微软原始的DataGridView头标题栏没有CheckBox的功能,郁闷了~~。
我在伍兄的博客找到有关于扩展DataGridVew在头标题栏添加全选功能按钮的功能(不是源码开源),而且他的这个程序集也不能满足我的需求,怎么办?
只有靠我自已去探索了,我在传统的DataGridView中实现了这个功能,但是整合进我的换肤组件中不能实现,Why? 我找了好友Strong一起研究,自已摸不清方向,最后还是他找到了问题点,可是却无法入手?(no any solution)
最后,经过自已的努力一步一步debug, 终于解决了问题,并整合进自已的换肤组件中,个人觉得有必要总结一下。
在总结技术点前,先展示一下我的成果,然后再做扩展说明,如下:
(图一)Office2007Blue效果
(图二) Office2007Silver效果
传统的解决方案
在传统的DataGridView上,实现基本上没有什么难处,只要按如下的步骤去操作就可以了。
添加一个DataGridViewColumnHeaderCellW.cs,继承DataGridViewColumnHeaderCell,
源码如下:
public class DataGridViewColumnHeaderCellW : DataGridViewColumnHeaderCell
{
public object HeaderTextDataSource { get; set; }
private Type _dataSourceType = null;
public Type DataSourceType
{
get
{
if (HeaderTextDataSource != null && _dataSourceType == null)
_dataSourceType = HeaderTextDataSource.GetType();
return _dataSourceType;
}
set { _dataSourceType = value; }
}
public string FieldName { get; set; }
public string Prefix { get; set; }
public string Suffix { get; set; } Point checkBoxLocation;
Size checkBoxSize;
bool _checked = false;
Point _cellLocation = new Point();
System.Windows.Forms.VisualStyles.CheckBoxState _cbState =
System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
public event datagridviewcheckboxHeaderEventHander OnCheckBoxClicked;
//绘制列头checkbox
protected override void Paint(System.Drawing.Graphics graphics,
System.Drawing.Rectangle clipBounds,
System.Drawing.Rectangle cellBounds,
int rowIndex,
DataGridViewElementStates dataGridViewElementState,
object value,
object formattedValue,
string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex,
dataGridViewElementState, value,
formattedValue, errorText, cellStyle,
advancedBorderStyle, paintParts);
Point p = new Point();
Size s = CheckBoxRenderer.GetGlyphSize(graphics,
System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
p.X = cellBounds.Location.X +
(cellBounds.Width / ) - (s.Width / ) - ; //列头checkbox的X坐标
p.Y = cellBounds.Location.Y +
(cellBounds.Height / ) - (s.Height / ); //列头checkbox的Y坐标
_cellLocation = cellBounds.Location;
checkBoxLocation = p;
checkBoxSize = s;
if (_checked)
_cbState = System.Windows.Forms.VisualStyles.
CheckBoxState.CheckedNormal;
else
_cbState = System.Windows.Forms.VisualStyles.
CheckBoxState.UncheckedNormal;
CheckBoxRenderer.DrawCheckBox
(graphics, checkBoxLocation, _cbState);
} /// <summary>
/// 点击列头checkbox单击事件
/// </summary>
protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
{ Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y);
if (p.X >= checkBoxLocation.X && p.X <=
checkBoxLocation.X + checkBoxSize.Width
&& p.Y >= checkBoxLocation.Y && p.Y <=
checkBoxLocation.Y + checkBoxSize.Height)
{
_checked = !_checked; //获取列头checkbox的选择状态
datagridviewCheckboxHeaderEventArgs ex = new datagridviewCheckboxHeaderEventArgs();
ex.CheckedState = _checked; object sender = new object();//此处不代表选择的列头checkbox,只是作为参数传递。应该列头checkbox是绘制出来的,无法获得它的实例 if (OnCheckBoxClicked != null)
{
OnCheckBoxClicked(sender, ex);//触发单击事件
this.DataGridView.InvalidateCell(this); } }
base.OnMouseClick(e);
}
在DataGridViewColumnHeaderCellW.cs内部,添加一个委托和继承EventArgs事件数据的基类:
public delegate void datagridviewcheckboxHeaderEventHander(object sender, datagridviewCheckboxHeaderEventArgs e); //定义包含列头checkbox选择状态的参数类
public class datagridviewCheckboxHeaderEventArgs : EventArgs
{
private bool checkedState = false; public bool CheckedState
{
get { return checkedState; }
set { checkedState = value; }
}
}
如何调用?
先在界面上添加一个DataGridView,并添加一列,选类型为DataGridViewCheckBoxColumn,在Form_Load事件中添加如下代码:
private void Form1_Load(object sender, EventArgs e)
{
DataGridViewColumnHeaderCellW ch = new DataGridViewColumnHeaderCellW();
ch.OnCheckBoxClicked += new datagridviewcheckboxHeaderEventHander(OnCheckBoxClicked);
//第三列为DataGridViewCheckBoxColumn
DataGridViewCheckBoxColumn checkboxCol = this.dataGridView1.Columns[] as DataGridViewCheckBoxColumn;
checkboxCol.HeaderCell = ch;
checkboxCol.HeaderCell.Value = string.Empty;//消除列头checkbox旁出现的文字
}
没题解决了!
展示一下,这个复选框暂放在最后一列,如下图:
这个真是灰头土脸,像是灰姑娘那么丑。
于是,我整合进我的换肤中,可是怎么也不能实现,标题栏就是不出来,结果成了如下图这样子:
最后经过一系列努力,定位问题在CellPainting事件中,重绘的过程把标题栏的checkbox效果覆盖了。
我在此事件中添加如下代码:
if (e.RowIndex == -)
{
if (!(_columnHeaderUpColor == Color.Transparent) && !(_columnHeaderDownColor == Color.Transparent) &&
!_columnHeaderUpColor.IsEmpty && !_columnHeaderDownColor.IsEmpty)
{
DrawLinearGradient(e.CellBounds, e.Graphics, _columnHeaderUpColor, _columnHeaderDownColor);
if (ShowColumnHeaderCheckBox)
{
e.Paint(e.ClipBounds, (DataGridViewPaintParts.All & ~DataGridViewPaintParts.Background));
}
else
{
DrawText(e);
}
e.Handled = true;
}
}
问题终于解决,但是在代码中为什么用ShowColumnHeaderCheckBox?
并不是所有的数据呈现功能都要有这个头标题栏复选框的功能,为了更好的兼容性,我在添加了这个属性,开发人员可以通过此属性灵活选择,默认是false。
public bool showColumnHeaderCheckBox; public bool ShowColumnHeaderCheckBox
{
get
{
return showColumnHeaderCheckBox;
}
set { showColumnHeaderCheckBox = value; }
}
在客户端这样去设就可以了。
private void Form1_Load(object sender, EventArgs e)
{
InitParameterList();
dataGridView1.ShowColumnHeaderCheckBox = true;//此处设为true
DataGridViewColumnHeaderCellW ch = new DataGridViewColumnHeaderCellW();
ch.OnCheckBoxClicked += new datagridviewcheckboxHeaderEventHander(OnCheckBoxClicked);
//第三列为DataGridViewCheckBoxColumn
DataGridViewCheckBoxColumn checkboxCol = this.dataGridView1.Columns[] as DataGridViewCheckBoxColumn;
checkboxCol.HeaderCell = ch;
checkboxCol.HeaderCell.Value = string.Empty;//消除列头checkbox旁出现的文字
}
总结
在研究一个新的东西时,我一般是先实现粗糙的功能,由浅入深渐渐细化这么一个演变的过程,毕竟灰姑娘一下要变成白雪公主也是要有个过程的。
元芳,你怎么看?
小菜的系统框架界面设计-数据的完美呈现(DataGridView扩展)的更多相关文章
- 小菜的系统框架界面设计-XiaoCai.WinformUI代码开源
我的源码分享 曾经,看到别人漂亮的系统界面,合理的布局,可是却没有提供源码,道理很简单,就是有偿提供,实际上对于有些技巧的东西也并没有多么难,只是不懂原理,感觉到困难罢了. 而对于刚毕业的我,求知欲强 ...
- 小菜的系统框架界面设计-灰姑娘到白雪公主的蜕变(工具条OutLookBar)
灰姑娘本身也有自已的优点,但是却可能因为外貌不讨人喜欢,要变成白雪公主却需要有很多勇气和决心去改变自已: 有一颗善良的心 讨人喜爱的外貌 --蜕变--> 我这里讲的是一个工具条的蜕变过程, ...
- Java日志系统框架的设计与实现
推荐一篇好的文章介绍java日志系统框架的设计的文章:http://soft.chinabyte.com/database/438/11321938.shtml 文章内容总结: 日志系统对跟踪调试.程 ...
- 基于Hadoop开发网络云盘系统客户端界面设计初稿
基于Hadoop开发网络云盘系统客户端界面设计初稿 前言: 本文是<基于Hadoop开发网络云盘系统架构设计方案>的第二篇,针对界面原型原本考虑有两个方案:1.类windows模式,文件夹 ...
- Winform XiaoCai.WinformUI 框架界面设计
开源用户界面和布局的套件XiaoCai.WinformUI(美化用户界面利器) http://www.cnblogs.com/aganqin/p/3400453.html 源码下载:https://g ...
- 苹果IOS与谷歌 android系统的UI设计原则
一.苹果为IOS的界面设计提出了六大原则: 1.整体美学 整体美学指的是一个应用的表现和行为与它的功能完美集成,传达连贯的信息. 人们关心一个应用是否提供它承诺的功能,但他们也被应用的外观和行为强烈影 ...
- [自制操作系统] BMP格式文件读取&图形界面系统框架/应用接口设计
本文将介绍在本人JOS中实现的简单图形界面应用程序接口,应用程序启动器,以及一些利用了图形界面的示例应用程序. 本文主要涉及以下部分: 内核/用户RW/RW调色板framebuffer共享区域 8bi ...
- [课程设计]Scrum 1.3 多鱼点餐系统开发进度(系统主界面框架&美化)
Scrum 1.3 多鱼点餐系统开发进度(系统主界面框架&美化) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选题:餐厅 ...
- 基于WPF系统框架设计(3)-Fluent Ribbon界面布局
一个系统框架除了功能菜单导航,有系统内容显示区域,系统状态栏. Silver: Blue: Black: 系统界面设计,就不进行技术细节介绍了,主题以框架设计为主,Xaml源码参考: <Flue ...
随机推荐
- C++学习17派生类的构造函数
基类的构造函数不能被继承,在声明派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数来完成.所以在设计派生类的构造函数时,不仅要考虑派生类新增的成员变量,还要考虑基类的成员变量,要让它们都 ...
- 基于lucene实现自己的推荐引擎
基于lucene实现自己的推荐引擎 推荐常用算法之-基于内容的推荐 推荐算法
- Delphi 中 paramstr 的用法及参数意义
原型 function paramstr(i:index):string 对于任何application paramstr(0)都默认代表的是应用程序的绝对路径.那 ...
- 虚拟机与CentOS的安装设置。
点击下一步: 点击稍后安装操作系统. 选择Linux系统,继续下一步 为了方便以后查找文件我们在这把虚拟机的名称改成自己喜欢的, 位置也是在大点的磁盘重新建一个专门存放的文件夹,做到规范. 在这推荐N ...
- nyoj 95 众数问题
点击打开链接 众数问题 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的成为该元素的重数, 多 ...
- LayoutInflater.Factory的夜间模式
自定义实现个Factory,可以用来解析自定义的属性.public interface Factory { /** * Hook you can supply that is called when ...
- ASP.Net软件工程师基础(一)
本人目前是一名有1年左右ASP.Net开发经验的的软件开发工程师,目前公司用的是MVC+EF+...做的网站.写这套总结性系列文章的目的有两个:一是帮助自己总结一下自己到底有多少斤两,而不是一味的学新 ...
- 常用正规js
1,得到网页上的链接地址: string matchString = @"<a[^>]+href=\s*(?:'(?<href>[^']+)'|"" ...
- Win2D 官方文章系列翻译 - 幕后绘制
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-offscreen-drawing/ 应用有时需要将图形绘制到并不立即显示的目标上.此类绘制动作被称作“幕后绘 ...
- Android开发-API指南-数据存储
Storage Options 英文原文:http://developer.android.com/guide/topics/data/data-storage.html 采集日期:2015-02-0 ...