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

VB.NET 如何根据ListView1勾选项从数据库正确填充ListView2

问题根因
  • 触发事件选择错误:你当前用MouseUp监听ListView1操作,只要鼠标在控件内抬起就会触发填充逻辑,不管是勾选、取消勾选、还是点击空白/列头都会执行函数,不符合仅勾选触发的需求。
  • 函数逻辑缺陷:
    • 遍历勾选项时多余执行ListView1.Items(i).Selected = True,会强制选中所有ListView1项,属于无用逻辑
    • 仅在存在勾选项(Yn=True)时操作ListView2,没有补充所有项都取消勾选时清空ListView2的逻辑
    • 操作ListView2时多余执行ListView3.Clear(),会误清空无关控件内容
修复后代码
Private Function selectionfromDeptTofillLv2() As Boolean 
    Dim i As Integer, Yn As Boolean
    Yn = False
    Dim strDept As String = ""
    ' 移除多余的选中所有项逻辑
    For i = 0 To ListView1.Items.Count - 1
        If ListView1.Items(i).Checked = True Then
            If Trim(strDept) <> "" Then strDept = strDept & ","
            strDept = strDept & Trim(ListView1.Items(i).Tag)
            Yn = True
        End If
    Next
    
    conn = GetConnect()
    conn.Open()
    If Yn = True Then
        Dim strSQL As String = "", strSQLdept As String = ""

        strSQL = "select SubName,SubDeptID from DepartmentSub where active=1"
        If Trim(strDept) <> "" Then strSQLdept = strSQLdept & " And DepartmentID In (" & strDept & ")" & " order by SubName"

        strSQL = strSQL & strSQLdept
        Dim cmd3 As SqlCommand = New SqlCommand(strSQL, conn)
        Dim sda3 As SqlDataAdapter = New SqlDataAdapter(cmd3)
        Dim dt3 As DataTable = New DataTable()

        sda3.Fill(dt3)

        With ListView2
            ' 移除多余的ListView3清空逻辑
            .Clear()
            .View = View.Details
            .GridLines = True
            .Columns.Clear()
            .Items.Clear()
            .Columns.Add(" ", 30)
            .Columns.Add("Sub Department Name", 250, HorizontalAlignment.Left)

            For Each row As DataRow In dt3.Rows
                Dim item As ListViewItem = New ListViewItem
                item.SubItems.Add(row("SubName").ToString())
                item.Tag = Val(row("SubDeptID").ToString)
                item.Checked = False
                .Items.Add(item)
            Next
        End With
    Else
        ' 无勾选项时清空ListView2
        ListView2.Clear()
    End If
    conn.Close()
    Return Yn
End Function

' 全选按钮逻辑
Private Sub CheckBox2_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox2.Click
    For Each lvitem As ListViewItem In Me.ListView1.Items
        lvitem.Checked = CheckBox2.Checked
    Next
    ' 全选时触发刷新,取消全选直接清空ListView2
    If CheckBox2.Checked Then
        selectionfromDeptTofillLv2()
    Else
        ListView2.Clear()
    End If
End Sub

' 替换原来的MouseUp事件,仅勾选状态变更时触发
Private Sub ListView1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles ListView1.ItemCheck
    ' 仅勾选操作触发刷新,取消勾选不触发,符合需求
    If e.NewValue = CheckState.Checked Then
        ' 延迟执行,等项的勾选状态更新完成后再调用函数
        Me.BeginInvoke(Sub() selectionfromDeptTofillLv2())
    End If
End Sub
补充注意事项
  • 当前代码直接拼接SQL语句存在SQL注入风险,建议改为参数化查询实现IN条件的传值
  • 如果需求是取消勾选时也同步刷新ListView2(移除对应部门的子项),只需要删除ItemCheck事件里的If e.NewValue = CheckState.Checked判断即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:06:02