如何无需选中行即可获取ListBox的SelectedValue等效值?
更优雅的ListBox绑定数据取值方案
嘿,我完全懂你现在的困扰——每次遍历都要手动选中行来获取值,不仅啰嗦,还可能导致界面闪烁或者触发不必要的事件,确实有更优的实现方式!
首先,咱们得搞清楚为什么lstUserRoleAll.Items(intCtr).ToString()会返回System.Data.DataRowView:因为你绑定的是DataTable,ListBox里的每一项本质上都是DataRowView对象(DataTable的行视图),直接调用ToString自然会返回它的类型名称,而不是你要的字段值。
下面给你两种更高效的解决方案:
方案1:直接转换Item为DataRowView取值
既然每个Item都是DataRowView,咱们直接把它转成对应的类型,然后通过字段名或者ValueMember来获取值:
For intCtr = 0 To lstUserRoleAll.Items.Count - 1 ' 把ListBox项转换为DataRowView Dim rowView As DataRowView = DirectCast(lstUserRoleAll.Items(intCtr), DataRowView) ' 两种取值方式:直接用字段名,或者用ListBox的ValueMember(更通用) Dim targetValue As Object = rowView(lstUserRoleAll.ValueMember) ' 或者:Dim targetValue As Object = rowView("UID") InsertUserRoles(targetValue) Next
方案2:直接遍历绑定的数据源(推荐)
既然你的ListBox绑定的是DataTable,完全可以跳过ListBox控件,直接遍历数据源的行,这样既避免了和UI控件交互,性能也更好:
' 先把数据源转成DataTable(如果之前的变量还在的话直接用rsSelectedGroups就行) Dim sourceTable As DataTable = DirectCast(lstUserRoleAll.DataSource, DataTable) For Each dataRow As DataRow In sourceTable.Rows Dim targetValue As Object = dataRow("UID") InsertUserRoles(targetValue) Next
为什么这两种方式更好?
- 不用频繁设置
SelectedIndex,不会触发SelectedIndexChanged事件(如果你的控件绑定了这个事件的话,能避免不必要的逻辑执行) - 不会造成界面上选中状态来回跳的问题,用户体验更流畅
- 方案2直接操作数据源,比通过UI控件取值更高效,数据量大的时候差距更明显
内容的提问来源于stack exchange,提问作者Doug Sholly
相关产品推荐
相关产品推荐

