加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

原创ComboBox详解—SelectedIndexChanged与属性值变化

(2009-10-13 16:23:06)
标签:

控件

行处

属性

数据源

null

it

分类: .Net

ComboBox控件(以下简称cb)在.net编程中很常用,下面把我个人使用这个空间时遇到的问题和学到的东西总结一下,供大家分享。

1.先说一下我对这个控件的习惯用法

DataSource绑定时,绑定一个dataTable(从数据库中取出来的);

用户交互时的事件调用,用SelectedIndexChanged()方法;

 

本文就以上面的用法为例,着重说一下SelectedIndexChanged()方法的执行过程和其间cb各属性值的变化过程。这些属性值(主要是他们的变化过程)如果没有弄的很清楚的话,在用的过程中很可能会出现想不到的错误,比如碰到null。主要是以下四个属性:

SelectedIndex

SelectedText

Text

SelectedValue.ToString()

 

2.SelectedIndexChanged()方法的执行

SelectedIndexChanged()方法在cb的DataSource发生改变时就会被调用,而不是用户在选一下时才会被调用。而且在cb的displaymember属性被赋值时,SelectedIndexChanged()方法也会被调用!

通常,如果用户交互(把cb拉下来选了某一项)之后,再在程序中读cb的属性是不会出问题的,因为用户交互之后,属性值就很明确了。问题就出在用户没有交互时,用到上面提到的属性值。这种情况是有的,因为cb显示出来后,默认显示DataSource里的第一项的值,而用户刚好就想用第一个值,那么他就不用再拉下来选一下了。

下面以我的代码为例,讲一下SelectedIndexChanged()方法是如何执行的。

代码如下:

 file:///C:/DOCUME~1/tfq/LOCALS~1/Temp/T}I8RP~YNMZG$32`@8TRF~Y.jpg

 

  file:///C:/DOCUME~1/tfq/LOCALS~1/Temp/61ULJUP]3K1]FNI9SJFU2KM.jpg   

其中数据源dt的内容如下:

 file:///C:/DOCUME~1/tfq/LOCALS~1/Temp/VQP(EKN)BP}])XLNA7MC@U3.jpg

我在316行处(也就是绑定cb的数据源时)打了一个断点,然后单步跟踪,执行过程如下:

(1)执行316行,绑定数据源;

(2)进入到SelectedIndexChanged()方法执行,而不是执行317行;

(3)SelectedIndexChanged()方法执行结束后,返回到316行处(但316行不会再执行了);

(4)执行317行,设定displaymember属性;

(5)进入到SelectedIndexChanged()方法执行;

(6)返回到317行,执行318行;

(7)执行319行,直到bindPayType()方法执行结束。

也就是说,绑定datasource和设定displaymember属性会触发cb的SelectedIndexChanged事件。而设定valuemember和tag的值则不会触发。

另外,如果设定displaymember属性在绑定datasource之前执行(316和317行互换一下),则设定displaymember属性不会触发SelectedIndexChanged事件。只有绑定datasource之后再设定displaymember才会触发SelectedIndexChanged事件。而且先设定displaymember与后设定,cb的Text的值(第二段代码输出测试)也不一样。先设定的话,执行SelectedIndexChanged()方法(注意只执行一次)时,cb的Text的值为"现金",就是dt的第一行对应元素的值;而后设定的话,第一次执行SelectedIndexChanged()方法,cb的Text的值是System.Data.DataRowView,第二次执行时才是"现金"。也就是说,在设定了displaymember后,cb的Text的值才会是Datasource里第一行对应元素的值。(这很合理,就该是这样)

 

3.不同阶段cb的各属性的值

以所贴代码为例(设定displaymember在绑定datasource之后),结果如下:

 

 

第一次执行

selectedIndexChanged

第二次执行

两次执行后(程序某处用到)

用户交互(选了cb的第二个)

SeletedIndex

0

0

0

1

SelectedText

Null

Null

Null

Null

Text

System.Data.

DataRowView

"现金"

"现金"

"代金券"

SelectedValue

.ToString()

同上

同左

"1"

"2"

 

可以看出SeletedIndex属性没用,尽量不要用。

 

4.一个问题

如果我定义一个变量schePayType(类成员变量),然后在SelectedIndexChanged()方法里执行

schePayType=cb.Text,而不是Console.out.writeLine(),也就是第二段代码如下:

 file:///C:/DOCUME~1/tfq/LOCALS~1/Temp/0R65`E09{K[8N_K`81L$HSB.jpg

那么,即便设定displaymember在绑定datasource之后,还是会只执行一遍SelectedIndexChanged()方法。

搞不懂为什么,难道是对外部变量进行赋值的原因?

 

5.应当注意的问题

如果想用户改选cb,就自动刷新某些数据,而程序中又用到SelectedIndexChanged()方法时,要注意SelectedIndexChanged()方法在用户还没交互时就很有可能被执行了(绑定datasource)。而这时如果读取cb的某些属性(作为查询数据库的条件),就有可能不是你认为的数据(有可能空,或者是System.Data.DataRowView)。

如果用上面提到的4个(其实是3个)属性做查询条件,那么

(1)查询前做一下判断(当然这个判断也有点麻烦);

(2)或者不采用用户改选cb就自动去查询的方法,而是让他再点个按钮再执行查询数据库。

(3)还有一种办法就是用SelectionChangeCommitted()方法,不过这个方法也有毛病。SelectionChangeCommitted()事件在你点某一个item时就发生,但此时combbox.Text的值没有变成你点的item对应的Text的值,而是还是原来的Text值。对于非绑定数据的combbox,因为没办法读SelectedValue的值,而只能读Text,所以最好就别用这个事件,而用Selected_Index_Changed()。

在我的另一篇文章里也有提到ComboBox:

http://blog.sina.com.cn/s/blog_5efa55090100djbq.html

今天在这里做个全面的总结。 

0

阅读 收藏 喜欢 打印举报/Report
后一篇:苏州行
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有