在DataGridView控件中实现冻结列分界线
我们在使用Office Excel的时候,有很多时候需要冻结行或者列。这时,Excel会在冻结的行列和非冻结的区域之间绘制上一条明显的黑线。如下图:

(图1)
WinForm下的DataGridView控件也能实现类似的冻结行或者列的功能(参见:http://msdn.microsoft.com/zh-cn/library/28e9w2e1(VS.85).aspx) ,但是呢,DataGridView控件默认不会在冻结列或者行的分界处绘制一个明显的分界线,这样的话,最终用户很难注意到当前有列或者行是冻结的。如下图所示:你能很快的找到那一列是Freeze的么?

(图2)
正是因为如此,我们如果能做出类似Excel的效果,就可以大大提高数据的可读性。
通常,我们如果想在现有的控件上多画点什么,就会去Override OnPaint方法,然后加入自己的OwnerDraw逻辑,但是呢在DataGridView上有一些困难:
1.如何确定冻结分界线的位置
2.如何保证分界线不会绘制到ScrollBar上
研究了一下,我们可以借用DataGridView提供的CellPainting方法。在DataGridView绘制每一个Cell的时候判断当前Cell是否是分界线所在的位置,然后进行绘制。最终做出的效果如下图:

(图3)
以下是DataGridView控件扩展源代码:
public class DataGridViewEx : DataGridView{ protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e) { base.OnCellPainting(e); // // Paints the Frozen line // int lastFreezeColumnIndex = GetDisplayColumnFrozenLineIndex(); int lastFreezeRowIndex = GetDisplayRowFrozenLineIndex(); bool drawRowLine = lastFreezeRowIndex != -1 && lastFreezeRowIndex == e.RowIndex; bool drawColumLine = lastFreezeColumnIndex != -1 && lastFreezeColumnIndex == e.ColumnIndex; if (drawRowLine || drawColumLine) { e.Paint(e.ClipBounds, e.PaintParts); if (drawColumLine) { e.Graphics.DrawLine(Pens.Black, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, this.ClientRectangle.Bottom); } if (drawRowLine) { e.Graphics.DrawLine(Pens.Black, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right, e.CellBounds.Bottom - 1); } e.Handled = true; } } private int GetDisplayColumnFrozenLineIndex() { int lastFreezeColumnIndex = -1; for (int i = 0; i < this.ColumnCount; i++) { DataGridViewColumn column = this.Columns[i]; if (column.Visible && column.Frozen) { lastFreezeColumnIndex = i; } else if (!column.Frozen) { return lastFreezeColumnIndex; } } return lastFreezeColumnIndex; } private int GetDisplayRowFrozenLineIndex() { int lastFreezeRowIndex = -1; for (int i = 0; i < this.RowCount; i++) { DataGridViewRow row = this.Rows[i]; if (row.Visible && row.Frozen) { lastFreezeRowIndex = i; } else if (!row.Frozen) { return lastFreezeRowIndex; } } return lastFreezeRowIndex; }} |
在DataGridView控件中实现冻结列分界线的更多相关文章
- 实现DataGridView控件中CheckBox列的使用
最近做WindowsForms程序,使用DataGridView控件时,加了一列做选择用,发现CheckBox不能选中.搜索后,要实现DataGridView的CellContentClick事件,将 ...
- 在DataGridView控件中加入ComboBox下拉列表框的实现
在DataGridView控件中加入ComboBox下拉列表框的实现 转自:http://www.cnblogs.com/luqingfei/archive/2007/03/28/691372.htm ...
- 在DataGridView控件中验证数据输入
实现效果: 知识运用: DataGridView控件的公共事件CellValidating //将System.Windows.Forms.DataGridViewCellValidatingEven ...
- DataGridView控件中添加ComboBox下拉列表框的实现
//ComboBox控件拖放到DataGridView控件的某个位置 //添加年龄下拉框 private void BindAge() { //我这里添加的是静态数据,一般都是从数据库读出来的,这里就 ...
- 在DataGridView控件中显示图片
实现效果: 知识运用: DataGridView控件的DataSource属性 实现代码: private void Form1_Load(object sender, EventArgs e) { ...
- 禁止DataGridView控件中添加和删除行
实现效果: 知识运用: DataGridView控件的AllowUserToAddRows AllowUserDeleteRows和ReadOnly属性 实现代码: private void btn_ ...
- 在DataGridView控件中启用换行
实现效果: 知识运用: DataGridView控件公共属性DefaultCellStyle的WrapMode属性 public DataGridViewTriState WrapMode { ge ...
- 设置DataGridView控件中字体的样式
实现效果: 知识运用: DataGridView控件的公共属性DefaultCellStyle的Font属性 public Font Font {get;set;} //获取或设置应用与DataGr ...
- 如何在winform DataGridView控件的DataGridViewButtonColumn按钮列中禁用按钮
原文:http://msdn.microsoft.com/en-us/library/ms171619(v=vs.85).ASPX public class DataGridViewDisableBu ...
随机推荐
- HDU 5483 Nux Walpurgis
Nux Walpurgis Time Limit: 8000ms Memory Limit: 131072KB This problem will be judged on HDU. Original ...
- enable apache2 rewrite_mod on ubuntu14.04
$ cd /etc/apache2/mods-enable $ ln -s rewrite.load ../mods-available/rewrite.load change "Allow ...
- hdu 1536 sg (dfs实现)
S-Nim Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- mac上安装ruby
(转:http://www.cnblogs.com/daguo/p/4097263.html) 以下代码区域,带有 $ 打头的表示需要在控制台(终端)下面执行(不包括 $ 符号) 步骤0 - 安装系统 ...
- Mahout0.9安装与配置(完全分布式模式下运行)
安装Mahout之前,一定要把hadoop装好,hadoop的安装方法可以参考我的前一篇随笔,我安装的是hadoop2.7.0,具体方法在此不做介绍. 1.首先下载相应版本的Mahout: axel ...
- BZOJ 4719 [Noip2016]天天爱跑步 ——树链剖分
一直以为自己当时是TLE了,但是再看发现居然WA? 然后把数组扩大一倍,就A掉了.QaQ 没什么好说的.一段路径分成两段考虑,上升的一段深度+时间是定值,下降的一段深度-时间是定值,然后打标记统计即可 ...
- Codeforces Round #345 (Div. 2) E. Table Compression(并查集)
传送门 首先先从小到大排序,如果没有重复的元素,直接一个一个往上填即可,每一个数就等于当前行和列的最大值 + 1 如果某一行或列上有重复的元素,就用并查集把他们连起来,很(不)显然,处于同一行或列的相 ...
- Snmp的学习总结——Snmp的基本概念
摘自:http://www.cnblogs.com/xdp-gacl/p/3978825.html 一.SNMP简单概述 1.1.什么是Snmp SNMP是英文"Simple Network ...
- 标准C程序设计七---02
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- LeetCode OJ--Implement strStr()
http://oj.leetcode.com/problems/implement-strstr/ 判断一个串是否为另一个串的子串 比较简单的方法,复杂度为O(m*n),另外还可以用KMP时间复杂度为 ...