热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

小菜的系统框架界面设计数据的完美呈现(DataGridView扩展)

背景今天在做系统报表的过程中,我想实现批量操作DataGridView中的数据,在列中加复选框,通过一个事件触发进行全选或取消࿰
背景

今天在做系统报表的过程中,我想实现批量操作DataGridView中的数据,在列中加复选框,通过一个事件触发进行全选或取消,可是在外面添加按钮,这种模式虽然能够实现,但是从系统界面设计的角度,美观和灵活性就差很多了,能否在DataGridView头标题栏上呈现复选框,通过这个头标题复选框来对这一列的复选框,这样是不是更灵活,也美观一点?

问题

可是,找了半天,发现微软原始的DataGridView头标题栏没有CheckBox的功能,郁闷了~~哭泣的脸

我在伍兄的博客找到有关于扩展DataGridVew在头标题栏添加全选功能按钮的功能(不是源码开源),而且他的这个程序集也不能满足我的需求,怎么办?

只有靠我自已去探索了,我在传统的DataGridView中实现了这个功能,但是整合进我的换肤组件中不能实现,Why? 我找了好友Strong一起研究,自已摸不清方向,最后还是他找到了问题点,可是却无法入手?(no any solution)

最后,经过自已的努力一步一步debug, 终于解决了问题,并整合进自已的换肤组件中,个人觉得有必要总结一下。

在总结技术点前,先展示一下我的成果,然后再做扩展说明,如下:

(图一)Office2007Blue效果

1

(图二) Office2007Silver效果

2

 

传统的解决方案

在传统的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 / 2) - (s.Width / 2) - 1; //列头checkbox的X坐标 p.Y = cellBounds.Location.Y +(cellBounds.Height / 2) - (s.Height / 2); //列头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);}///

/// 点击列头checkbox单击事件 /// protected override void OnMouseClick(DataGridViewCellMouseEventArgs e){Point p &#61; new Point(e.X &#43; _cellLocation.X, e.Y &#43; _cellLocation.Y);if (p.X >&#61; checkBoxLocation.X && p.X <&#61;checkBoxLocation.X &#43; checkBoxSize.Width&& p.Y >&#61; checkBoxLocation.Y && p.Y <&#61;checkBoxLocation.Y &#43; checkBoxSize.Height){_checked &#61; !_checked;//获取列头checkbox的选择状态 datagridviewCheckboxHeaderEventArgs ex &#61; new datagridviewCheckboxHeaderEventArgs();ex.CheckedState &#61; _checked;object sender &#61; new object();//此处不代表选择的列头checkbox&#xff0c;只是作为参数传递。应该列头checkbox是绘制出来的&#xff0c;无法获得它的实例 if (OnCheckBoxClicked !&#61; null){OnCheckBoxClicked(sender, ex);//触发单击事件 this.DataGridView.InvalidateCell(this);}}base.OnMouseClick(e);}

在DataGridViewColumnHeaderCellW.cs内部&#xff0c;添加一个委托和继承EventArgs事件数据的基类:

public delegate void datagridviewcheckboxHeaderEventHander(object sender, datagridviewCheckboxHeaderEventArgs e);//定义包含列头checkbox选择状态的参数类 public class datagridviewCheckboxHeaderEventArgs : EventArgs{private bool checkedState &#61; false;public bool CheckedState{get { return checkedState; }set { checkedState &#61; value; }}}

如何调用?

先在界面上添加一个DataGridView,并添加一列&#xff0c;选类型为DataGridViewCheckBoxColumn,在Form_Load事件中添加如下代码:

private void Form1_Load(object sender, EventArgs e){DataGridViewColumnHeaderCellW ch &#61; new DataGridViewColumnHeaderCellW();ch.OnCheckBoxClicked &#43;&#61; new datagridviewcheckboxHeaderEventHander(OnCheckBoxClicked);//第三列为DataGridViewCheckBoxColumn DataGridViewCheckBoxColumn checkboxCol &#61; this.dataGridView1.Columns[0] as DataGridViewCheckBoxColumn;checkboxCol.HeaderCell &#61; ch;checkboxCol.HeaderCell.Value &#61; string.Empty;//消除列头checkbox旁出现的文字 }

没题解决了!

展示一下&#xff0c;这个复选框暂放在最后一列&#xff0c;如下图:

QQ图片20130621184411

这个真是灰头土脸&#xff0c;像是灰姑娘那么丑。

于是&#xff0c;我整合进我的换肤中&#xff0c;可是怎么也不能实现&#xff0c;标题栏就是不出来,结果成了如下图这样子:

3

最后经过一系列努力&#xff0c;定位问题在CellPainting事件中&#xff0c;重绘的过程把标题栏的checkbox效果覆盖了。

我在此事件中添加如下代码:

if (e.RowIndex &#61;&#61; -1){if (!(_columnHeaderUpColor &#61;&#61; Color.Transparent) && !(_columnHeaderDownColor &#61;&#61; 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 &#61; true;}}

问题终于解决&#xff0c;但是在代码中为什么用ShowColumnHeaderCheckBox?

并不是所有的数据呈现功能都要有这个头标题栏复选框的功能&#xff0c;为了更好的兼容性&#xff0c;我在添加了这个属性&#xff0c;开发人员可以通过此属性灵活选择,默认是false。

public bool showColumnHeaderCheckBox;public bool ShowColumnHeaderCheckBox{get{return showColumnHeaderCheckBox;}set { showColumnHeaderCheckBox &#61; value; }}

在客户端这样去设就可以了。

private void Form1_Load(object sender, EventArgs e){InitParameterList();dataGridView1.ShowColumnHeaderCheckBox &#61; true;//此处设为trueDataGridViewColumnHeaderCellW ch &#61; new DataGridViewColumnHeaderCellW();ch.OnCheckBoxClicked &#43;&#61; new datagridviewcheckboxHeaderEventHander(OnCheckBoxClicked);//第三列为DataGridViewCheckBoxColumn DataGridViewCheckBoxColumn checkboxCol &#61; this.dataGridView1.Columns[0] as DataGridViewCheckBoxColumn;checkboxCol.HeaderCell &#61; ch;checkboxCol.HeaderCell.Value &#61; string.Empty;//消除列头checkbox旁出现的文字 }

总结

在研究一个新的东西时&#xff0c;我一般是先实现粗糙的功能&#xff0c;由浅入深渐渐细化这么一个演变的过程&#xff0c;毕竟灰姑娘一下要变成白雪公主也是要有个过程的。

元芳&#xff0c;你怎么看&#xff1f;捧腹大笑

转:https://www.cnblogs.com/aganqin/p/3148893.html



推荐阅读
author-avatar
ThanksGiven
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有