You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于CheckedListBox1选中值从SQL Server填充CheckedListBox2

问题原因
  • ItemCheck事件触发时,当前操作项的勾选状态尚未更新到控件,直接调用GetItemCheckState获取的是修改前的旧状态
  • 循环步长错误设置为Step i + 1,会导致遍历跳项,无法遍历所有CheckedListBox1的条目
  • dt2未做初始化清空,多次查询会叠加冗余数据
  • 每次查询部门子项后直接重新绑定CheckedListBox2数据源,最终只会保留最后一个选中部门的子部门,无法合并所有选中部门的子项
  • 数据库连接未手动释放,存在资源泄漏风险
修正后完整代码

首先在窗体层声明统一的连接字符串,避免重复编写:

' 窗体级声明连接字符串,统一管理
Private ReadOnly connStr As String = "Data Source=192.168.200.36;user id=sa;password=XXXX@123;database=XXXXXXX"

原有填充CheckedListBox1的方法可保留不变,以下为级联加载的核心实现:

Private Sub fillChkboxListSub(Optional e As ItemCheckEventArgs = Nothing)
    Dim dt2 As New DataTable()
    ' 先收集所有选中的DepartmentID
    Dim checkedDeptIds As New List(Of String)()
    For i = 0 To CheckedListBox1.Items.Count - 1
        Dim checkState As CheckState = CheckedListBox1.GetItemCheckState(i)
        ' 如果是当前正在修改的项,用新状态替代旧状态
        If e IsNot Nothing AndAlso i = e.Index Then
            checkState = e.NewValue
        End If
        If checkState = CheckState.Checked Then
            Dim deptId As String = CType(CheckedListBox1.Items(i), DataRowView)("DepartmentID").ToString()
            ' 如果DepartmentID是数值类型,此处无需拼接单引号
            checkedDeptIds.Add("'" & deptId & "'")
        End If
    Next

    ' 没有选中部门时清空CheckedListBox2
    If checkedDeptIds.Count = 0 Then
        CheckedListBox2.DataSource = Nothing
        Return
    End If

    ' 拼接IN查询条件,一次查询所有选中部门的子部门,避免多次查询数据库
    Dim sqlStr As String = $"select SubName,SubDeptID from DepartmentSub where active=1 and DepartmentID in ({String.Join(",", checkedDeptIds)}) order by SubName"
    ' Using关键字会自动释放连接资源,无需手动关闭
    Using conn As New SqlConnection(connStr)
        Using sda As New SqlDataAdapter(sqlStr, conn)
            sda.Fill(dt2)
        End Using
    End Using

    ' 绑定数据到CheckedListBox2
    CheckedListBox2.DataSource = dt2
    CheckedListBox2.DisplayMember = "SubName"
    CheckedListBox2.ValueMember = "SubDeptID"
End Sub

修改ItemCheck事件的调用逻辑,传入当前事件参数:

Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
    fillChkboxListSub(e)
End Sub
实现逻辑说明
  • 每次勾选操作触发时,先统一收集所有处于勾选状态的部门ID,包含当前正在修改的项的最新状态
  • 采用IN查询一次性拉取所有选中部门的子部门,减少数据库交互次数
  • 每次绑定前清空旧数据,确保CheckedListBox2只保留当前选中部门对应的子部门
  • 使用Using关键字自动释放数据库连接资源,无需手动关闭连接

内容的提问来源于stack exchange,提问作者gurpreet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 07:48:04