我们在使用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控件中实现冻结列分界线的更多相关文章

  1. 实现DataGridView控件中CheckBox列的使用

    最近做WindowsForms程序,使用DataGridView控件时,加了一列做选择用,发现CheckBox不能选中.搜索后,要实现DataGridView的CellContentClick事件,将 ...

  2. 在DataGridView控件中加入ComboBox下拉列表框的实现

    在DataGridView控件中加入ComboBox下拉列表框的实现 转自:http://www.cnblogs.com/luqingfei/archive/2007/03/28/691372.htm ...

  3. 在DataGridView控件中验证数据输入

    实现效果: 知识运用: DataGridView控件的公共事件CellValidating //将System.Windows.Forms.DataGridViewCellValidatingEven ...

  4. DataGridView控件中添加ComboBox下拉列表框的实现

    //ComboBox控件拖放到DataGridView控件的某个位置 //添加年龄下拉框 private void BindAge() { //我这里添加的是静态数据,一般都是从数据库读出来的,这里就 ...

  5. 在DataGridView控件中显示图片

    实现效果: 知识运用: DataGridView控件的DataSource属性 实现代码: private void Form1_Load(object sender, EventArgs e) { ...

  6. 禁止DataGridView控件中添加和删除行

    实现效果: 知识运用: DataGridView控件的AllowUserToAddRows AllowUserDeleteRows和ReadOnly属性 实现代码: private void btn_ ...

  7. 在DataGridView控件中启用换行

    实现效果: 知识运用: DataGridView控件公共属性DefaultCellStyle的WrapMode属性 public DataGridViewTriState WrapMode {  ge ...

  8. 设置DataGridView控件中字体的样式

    实现效果: 知识运用: DataGridView控件的公共属性DefaultCellStyle的Font属性 public Font Font  {get;set;} //获取或设置应用与DataGr ...

  9. 如何在winform DataGridView控件的DataGridViewButtonColumn按钮列中禁用按钮

    原文:http://msdn.microsoft.com/en-us/library/ms171619(v=vs.85).ASPX public class DataGridViewDisableBu ...

随机推荐

  1. 【管理】个人主义—>集体主义

    导读:这个月作为学术部负责人,暴露了很多问题,个人的,集体的!我需要思考的,有很多.现在,我反思图书馆丢书这件事的处理方案:我虽然站在了管理层,却做着员工干的事儿.以一种个人主义.英雄主义去做事儿.却 ...

  2. .NET重构(七):VS报表的制作

    导读:机房做到最后阶段,就是报表的制作了.想到第一次,是借助外部控件进行实现的,这次采用VS进行编写,在这个软件中,有自带的报表编辑工具,更加的方便和简洁,现在就对这一块的学习,进行总结. 一.报表制 ...

  3. Oracle spool 用法小结

    关于SPOOL(SPOOL是SQLPLUS的命令,不是SQL语法里面的东西.) 对于SPOOL数据的SQL,最好要自己定义格式,以方便程序直接导入,SQL语句如: select taskindex|| ...

  4. JSF框架整理

    JSP体系结构: JSF主要优势之一就是它既是Java web 应用程序的用户界面标准又是严格遵循 模型-视图-控制器(MVC)设计模式的框架. 用户界面代码(视图)和应用程序数据和逻辑(模型)的清晰 ...

  5. FZU 2020 :组合 【lucas】

    Problem Description 给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数.例如C(5,2) = 10, C(4,2) = 6.可是当n,m比较大的时候,C(n,m)很大! ...

  6. 【基础操作】FFT / DWT / NTT / FWT 详解

    1. 2. 点值表示法 假设两个多项式相乘后得到的多项式 的次数(最高次项的幂数)为 $n$.(这个很好求,两个多项式的最高次项的幂数相加就得到了) 对于每个点,要用 $O(n)$ 的时间 把 $x$ ...

  7. 【2018.9.20】JOI 2017 Final T3「JOIOI 王国 / The Kingdom of JOIOI」

    题目链接 题目描述 JOIOI 王国是一个 $H$ 行 $W$ 列的长方形网格,每个 $1\times 1$ 的子网格都是一个正方形的小区块.为了提高管理效率,我们决定把整个国家划分成两个省 $JOI ...

  8. 陌上花开(bzoj 3262)

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...

  9. 洛谷 [P1995] 程序自动分析

    并查集+ 离散化 首先本题的数据范围很大,需要离散化, STL离散化代码: //dat是原数据,id是编号,sub是数据的副本 sort(sub + 1, sub + tot + 1); size = ...

  10. ElasticSearch分词器

    什么是分词器? 分词器,是将用户输入的一段文本,分析成符合逻辑的一种工具.到目前为止呢,分词器没有办法做到完全的符合人们的要求.和我们有关的分词器有英文的和中文的.英文的分词器过程:输入文本-关键词切 ...