近日在用C#编程过程中遇到一个非常罕见的异常,用了3天时间终于给解决掉。问题虽然解决,但是迷惑仍然未解,还往高手能指点迷津。
我用一个组合框来显示数据表中的数据,其中赋值语句是这样的(在加载主窗体过程中执行):
DataTable tb = Oracle.GetDept(1); //把取得的数据表赋给tb,此语句无问题,tb内容很正常,有8条数据
If(tb.Rows.Count < 1) return; //此语句无问题
Cmb.DataSource = tb; //为组合框指定数据源
Cmb.DisplayMember = “NAME”; //为组合框指定显示成员,字段类型为Varchar2长度50,名字为NAME
Cmb.ValueMember = “ID”; //为组合框指定值成员,字段类型为Integer,名字为ID
//程序在此处出现异常,提示“无效的列名”
然后,主窗体出现,组合框内数据显示的居然是字段“ID”的内容,而组合框的SelectedValue的值却是System.Data.DataRowView.
难道是数据源绑定中语句顺序有误?调换一下顺序试试!于是小弟将数据源绑定语句该为:
Cmb.DisplayMember = “NAME”; //为组合框指定显示成员,字段类型为Varchar2长度50,名字为NAME
Cmb.ValueMember = “ID”; //为组合框指定值成员,字段类型为Integer,名字为ID
Cmb.DataSource = tb; //为组合框指定数据源
保存,编译,重新执行,没有异常抛出!哈哈,难道真的是顺序问题,只能把数据表放在最后?然而执行的结果却是这样的:组合框内数据居然全部显示为“System.Data.DataRowView”,但是组合框的SelectedValue值却是正常的,显示的是数据表内“ID”字段的内容。
这就奇怪了,为什么呢?莫非文本框的属性引起了此异常?
于是逐个检查属性,发现属性非常正常。和另一窗口中的组合框属性值相同,但是为什么这里不能够正常显示呢?难道数据表的问题?
然后小弟把数据表tb指定给另一窗体中显示正常的组合框,编译执行。奇怪,显示非常正常。看来不是数据源的问题。那问题就究竟在哪里呢?难道是构造函数引起的。
检查构造函数,单步跟踪,没有问题。组合框仍然无法正常显示!
然后再单步跟踪调试,发现一个问题:
程序在执行完了Cmb.DataSource = tb; 后居然一下跳到组合框的SelectedIndexChanged事件中,执行完此事件后,才跳回到下一步:
Cmb.DisplayMember = “NAME”;
Cmb.ValueMember = “ID”;
怪了,为什么呢?我没有指定它的索引值也没有触发相关时间啊!难道是数据表在装载过程中,引起了索引值被非法改变的情况,所以才引发了SelectedIndexChanged事件,但是程序在执行到这一步时,组合框还不知道显示成员和值成员是谁,所以才会找不到SelectedValue,而是用System.Data.DataRowView代替,所以才会抛出异常,无效的列名?
那好,把下面语句:
Cmb.DisplayMember = “NAME”;
Cmb.ValueMember = “ID”;
加到SelectedIndexChanged事件的处理语句中。
编译,保存,老天,居然正常了!!!!!!!!!!!!!!!!
但是为什么呢,为什么给组合框指定数据源会引发SelectedIndexChanged事件???????小弟仍然不能理解,还望有高手能指点一二,不然虽然问腿解决,但仍然不明就里,糊里糊涂!
(2006-07-31 补充说明)
今天突然发现,原来运行良好的程序,突然出现问题,如前所述,仍然是数据源绑订到组合框的问题,发现指定的显示成员和值成员的大小写必须严格对照数据库中的字段大小写,不然也会出错。