• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
pangzipangpang走过的路
博客园    首页    新随笔    联系   管理    订阅  订阅

每日点滴之贰零零玖年拾月壹拾玖日

这两天头疼于DataGridView的输入验证和排序问题,琢磨了两天,也查阅了相关的经验,终于找到解决方法,以下摘自http://www.51code.net/articles/dotnet/DotNet100186.html:

DataGridView中的数据格式失效和排序异常
datagridview是一个功能强大的windows forms控件,常用于数据录入和呈现,既可以作为独立的表格数据容器,也可以绑定到数据集(如:dataset/datatable或实现了ibindinglist接口的集合)。同时,在数据呈现时提供了单元格、表格列或表格行的格式化功能,如:对齐、字体、颜色、数据格式等,也提供了单击表格列头自动排序的能力。通常,程序中使用datagridviewtextboxcolumn处理字符与数值型数据。实际应用时却经常碰到如下两个令人困惑的现象:
在定义表格列时设置了defaultcellstyle的format格式,如:两位小数数值的格式是n2,但输入数据时并没有按这个要求显示;
直接给表格某列的单元赋不同类型的值,如: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将按该格式显示。同时,排序也不会出现类型不一致的情况。

 

posted @ 2009-10-19 10:59  pangzi  阅读(268)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3