博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在DataGridView控件中实现冻结列分界线
阅读量:4621 次
发布时间:2019-06-09

本文共 2073 字,大约阅读时间需要 6 分钟。

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

 

 

(图1)

WinForm下的DataGridView控件也能实现类似的冻结行或者列的功能(参见: ,但是呢,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;
 
    
}
}

转载于:https://www.cnblogs.com/sjqq/p/7554015.html

你可能感兴趣的文章
排序算法3---直接插入排序算法
查看>>
用matalb、python画聚类结果图
查看>>
JDK提供的几个基本注解
查看>>
Firebird数据库值得信赖吗?为什么我要在开发中选择...
查看>>
__rept__和__str__
查看>>
docker镜像基本操作
查看>>
算法第五章上机实践报告
查看>>
SHELL学习笔记----IF条件判断,判断条件
查看>>
RegisterWaitForSingleObject的使用
查看>>
UML第三次作业
查看>>
000 Python教程
查看>>
2013能量篇终止,2014精致篇起航
查看>>
力扣——分数排名(数据库的题
查看>>
力扣——行程与用户(数据库的题
查看>>
3.java基础语法(下)
查看>>
ios 11 系统CPU过高,xib中textfield使用导致出过高
查看>>
JS应用(资料很全)
查看>>
JAVA 自动生成对应数据库表的JPA代码工具
查看>>
一个用 C 语言写的迷你版 2048 游戏,仅仅有 500个字符
查看>>
Linux虚拟文件系统VFS解决
查看>>