DataGridView中的数据格式失效和排序异常

来源:互联网 发布:合工大网络教育 编辑:程序博客网 时间:2024/05/17 09:29

问题与原因

DataGridView是一个功能强大的Windows Forms控件,常用于数据录入和呈现,既可以作为独立的表格数据容器,也可以绑定到数据集(如:DataSet/DataTable或实现了IBindingList接口的集合)。同时,在数据呈现时提供了单元格、表格列或表格行的格式化功能,如:对齐、字体、颜色、数据格式等,也提供了单击表格列头自动排序的能力。通常,程序中使用DataGridViewTextBoxColumn处理字符与数值型数据。实际应用时却经常碰到如下两个令人困惑的现象:
  1. 在定义表格列时设置了DefaultCellStyle的Format格式,如:两位小数数值的格式是N2,但输入数据时并没有按这个要求显示;
  2. 直接给表格某列的单元赋不同类型的值,如:dataGridView1.Rows[0].Cells[0].Value = 1、dataGridView1.Rows[1].Cells[0].Value = 1.1,此时点该列表头自动排序,将抛出异常。

1)DefaultCellStyle.Format只针对数值型数据

在DataGridView的单元格dataGridView1.Rows[1].Cells[0].Value是Object类型,可以接受任何类型的数据。如果直接录入单元格内容,那么DataGridView认为录入的数据类型为String,就不会按照格式Format的进行数据的自动格式化,也就看不到希望的格式化后的显示结果。

直接给单元格赋值也存在这个问题。如果给的值是整数、实数,可以呈现格式化的结果。如果给的值是字符文本,将保持默认的文本格式。

2)同列单元的数据类型不一致引发排序异常

如果直接给同一列的两个单元格赋不同数据类型的值,例如:整型/实型、整型/字符型,等等:
dataGridView1.Rows.Add(5);dataGridView1.Rows[0].Cells[0] = 1;dataGridView1.Rows[1].Cells[0] = 1.1;
上述代码中,当值为1时,单元格的ValueType为int;为1.1时,单元格的ValueType为double。那么,点击该列做自动排序时将抛出异常“对象必须是Double。”或“对象必须是Int32。”,如果赋给的是整型和字符串,则抛出异常:“对象必须是String。”或“对象必须是Int32。”其原因为,排序时要求当前列的数据类型全部相同或值为null,否则使用内置的ICompare做排序操作将抛出异常。

解决的方法

1)使用DataTable数值型字段

如果DataGridView绑定到DataTable,且指定表格列Format的字段是数值型的(Int/Double/Single/Decimal),那么显示数据时将自动格式化,排序等操作也不存在问题。此时,如果输入非数值型数据,例如:12..3,将引发DataGridView异常。

2)编辑单元格后转换为数值型

在DataGridView直接录入单元格值并离开后,将发生一系列的CellXXX事件,顺序依次为:CellLeave、CellValidating、CellParsing、CellValueChanged、CellValidated、CellEndEdit,等等。其中,在单元格的值已经变化(Changed)的情况下,单元格退出编辑模式时发生CellParsing事件,此时可以做数据类型转换和数值转换工作:
private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e){    decimal cellValue = 0;    string cellContent = e.Value as string;  // DataGridViewTextBoxColumn保证是string类型    if (!string.IsNullOrEmpty(cellContent))    {        decimal.TryParse(cellContent, out cellValue);    }    e.Value = cellValue;  // 强制转换数据类型为decimal    e.ParsingApplied = true;}

给事件的e.Value赋值的同时,单元格的ValueType自动获得对应值的类型(上述代码为decimal)。此时,如果定义了列或单元格的数值显示格式Format,DataGridView将按该格式显示。同时,排序也不会出现类型不一致的情况。



http://blog.csdn.net/hulihui/article/details/3447380