DataGridView控件显示行号的正确代码及分析

 更新时间:2013年08月19日 09:17:07   作者:  
今天要用到DataGridView,想给它动态的显示行号。于是在网上找了一下解决方法。结果发现了不少问题。然而就是这么一段有错的代码,几乎充斥着整个互联网,千篇一律的COPY,没有一个人纠正

前些天在写个小程序,用到DataGridView,想给它动态的显示行号。不是很费劲GOOGLE了一下,这GOOGLE不要紧,发现了不少问题。以下基本上都是GOOGLE搜索出来的网上的一些解决方法,千篇一律都是这样的:

复制代码 代码如下:

private void DataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {

            for (int i = 0; i < e.RowCount; i++)
            {
                this.dgvKBRollUp.Rows[e.RowIndex + i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                this.dgvKBRollUp.Rows[e.RowIndex + i].HeaderCell.Value = (e.RowIndex + i + 1).ToString();
            }
            for (int i = e.RowIndex + e.RowCount; i < this.dgvKBRollUp.Rows.Count; i++)
            {
                this.dgvKBRollUp.Rows[i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                this.dgvKBRollUp.Rows[i].HeaderCell.Value = (i + 1).ToString();
            }            
        }

private void DataGridView1_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {

            for (int i = 0; i < e.RowCount; i++)
            {
                this.dgvKBRollUp.Rows[e.RowIndex + i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                this.dgvKBRollUp.Rows[e.RowIndex + i].HeaderCell.Value = (e.RowIndex + i + 1).ToString();
            }
            for (int i = e.RowIndex + e.RowCount; i < this.dgvKBRollUp.Rows.Count; i++)
            {
                this.dgvKBRollUp.Rows[i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                this.dgvKBRollUp.Rows[i].HeaderCell.Value = (i + 1).ToString();
            }            
        }

只要用过这段代码的人就应该发现这段代码是运行出错的。原因就出在RowsRemoved事件里,会抛出一个Index outof range的异常。然而就是这么一段有错的代码,几乎充斥着整个互联网,千篇一律的COPY,没有一个人纠正。

先说下这段代码出错的原因吧:
在RowsRemoved事件里,最开始生成DataGridView的数据的时候,也是会触发这个事件的。这个时候DataGridView控件的Rows.Count就是0。那下面这行代码就有问题了:
复制代码 代码如下:

this.dgvKBRollUp.Rows[e.RowIndex + i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;

e.RowIndex + i,这里对应的是Rows[0],但是Rows.Count还是0啊,Rows[0]是不存在的。要存在Rows[0]起码DataGridView控件要有一行才行。为了避免这个错误,小小的修改代码就行了:
复制代码 代码如下:

private void dgvKBRollUp_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            if (dgvKBRollUp.Rows.Count != 0)
            {
                for (int i = 0; i < e.RowCount; i++)
                {
                    this.dgvKBRollUp.Rows[e.RowIndex + i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                    this.dgvKBRollUp.Rows[e.RowIndex + i].HeaderCell.Value = (e.RowIndex + i + 1).ToString();
                }

                for (int i = e.RowIndex + e.RowCount; i < this.dgvKBRollUp.Rows.Count; i++)
                {
                    this.dgvKBRollUp.Rows[i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                    this.dgvKBRollUp.Rows[i].HeaderCell.Value = (i + 1).ToString();
                }

            }

只要加上一个对Rows.Count的判断就可以避免这个错误。希望网上的一些COPY的朋友也要注意了,以后COPY过来的时候,自己还是要动手验证一下。将一个错误的信息胡乱的传播是对一些新手以及自己都不怎么好的。

最后附上微软MSDN里面关于e.RowIndex和e.RowCount的一段代码:

复制代码 代码如下:

System.Text.StringBuilder messageBoxCS = new System.Text.StringBuilder();
            messageBoxCS.AppendFormat("{0} = {1}", "RowIndex", e.RowIndex);
            messageBoxCS.AppendLine();
            messageBoxCS.AppendFormat("{0} = {1}", "RowCount", e.RowCount);
            messageBoxCS.AppendLine();
            MessageBox.Show(messageBoxCS.ToString(), "RowsRemoved Event");

通过这段代码你可以很轻松地跟踪事件参数里的e.RowIndex和e.RowCount的值。当然你可以DEBUG,一样的。我就是DEBUG的O(∩_∩)O~

相关文章

  • C#正则函数用法实例【匹配、替换、提取】

    C#正则函数用法实例【匹配、替换、提取】

    这篇文章主要介绍了C#正则函数用法,结合实例形式分析了C#基于正则的匹配、替换、提取相关操作技巧,需要的朋友可以参考下
    2017-01-01
  • C#中的Task.Delay()和Thread.Sleep()区别(代码案例)

    C#中的Task.Delay()和Thread.Sleep()区别(代码案例)

    Task.Delay(),async/await和CancellationTokenSource组合起来使用可以实现可控制的异步延迟。本文通过多种代码案例给大家分析C#中的Task.Delay()和Thread.Sleep()知识,感兴趣的朋友一起看看吧
    2021-06-06
  • .NET中保证线程安全的高级方法Interlocked类使用介绍

    .NET中保证线程安全的高级方法Interlocked类使用介绍

    这篇文章主要介绍了.NET中保证线程安全的高级方法Interlocked类使用介绍,Interlocked类可以为为多个线程共享的变量提供原子操作,需要的朋友可以参考下
    2014-07-07
  • C#正则表达式获取下拉菜单(select)的相关属性值

    C#正则表达式获取下拉菜单(select)的相关属性值

    这篇文章主要介绍了C#正则表达式获取下拉菜单(select)的相关属性值,比如可以获得name属性的值、value值、指定值,需要的朋友可以参考下
    2014-07-07
  • C#中sleep和wait的区别分析

    C#中sleep和wait的区别分析

    这篇文章主要介绍了C#中sleep和wait的区别分析,有助于深入理解C#中线程的原理与使用技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • C# WPF后台动态添加控件实战教程

    C# WPF后台动态添加控件实战教程

    最近尝试用wpf在后台动态添加控件,所以下面这篇文章主要给大家介绍了关于C# WPF后台动态添加控件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • C#中如何自定义配置上周和本周起始日来查询业务数据(思路详解)

    C#中如何自定义配置上周和本周起始日来查询业务数据(思路详解)

    在C#中并没有封装的方法根据我们需要来直接获取上一周某天到某天、本周某天到某天,所以需要我们自己封装方法来实现(我们也可以按照这个思路使用其他语言来实现),感兴趣的朋友跟随小编一起看看吧
    2023-09-09
  • C#创建一个Word并打开的方法

    C#创建一个Word并打开的方法

    这篇文章主要介绍了C#创建一个Word并打开的方法,实例分析了C#操作word的常用技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • C#查看/写入日志到Windows事件查看器的操作方法

    C#查看/写入日志到Windows事件查看器的操作方法

    Windows 操作系统将与计算机的系统性能、应用程序和安全方面相关的每个事件记录在 C:\WINDOWS\system32\winevt 的日志中,事件查看器从这些原始事件日志中读取信息,然后以可读格式呈现信息,本文介绍了C#如何查看/写入日志到Windows事件查看器,需要的朋友可以参考下
    2024-09-09
  • C#泛型集合类System.Collections.Generic

    C#泛型集合类System.Collections.Generic

    这篇文章介绍了C#中的泛型集合类System.Collections.Generic,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05

最新评论