WinForm的DataGridView重复添加CheckBox列问题求助
问题原因
每次ComboBox的SelectedIndexChanged事件触发都会调用一次GetRecords方法,你将CheckBox列插入、全选CheckBox控件添加、点击事件绑定的逻辑都写在了这个方法里,方法每执行一次就会新增1个CheckBox列、重复绑定多次相同事件,调用多少次就会出现多少个重复列。
解决方法
- 将列初始化、控件添加、事件绑定的逻辑拆分到窗体加载事件中,全局只执行一次
- 调整数据绑定逻辑,避免重复生成列
- 原代码使用字符串拼接SQL存在注入风险,建议替换为参数化查询
修正后代码示例
窗体加载事件逻辑
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' 全局仅初始化一次 DataGridView1.AutoGenerateColumns = False ' 添加CheckBox列 Dim checkBoxColumn As DataGridViewCheckBoxColumn = New DataGridViewCheckBoxColumn() checkBoxColumn.HeaderText = "" checkBoxColumn.Width = 30 checkBoxColumn.Name = "checkBoxColumn" DataGridView1.Columns.Insert(0, checkBoxColumn) ' 添加表头全选CheckBox Dim headerCellLocation As Point = Me.DataGridView1.GetCellDisplayRectangle(0, -1, True).Location headerCheckBox.Location = New Point(headerCellLocation.X + 8, headerCellLocation.Y + 2) headerCheckBox.BackColor = Color.White headerCheckBox.Size = New Size(18, 18) DataGridView1.Controls.Add(headerCheckBox) ' 绑定事件,仅绑定一次 AddHandler headerCheckBox.Click, AddressOf HeaderCheckBox_Clicked AddHandler DataGridView1.CellContentClick, AddressOf DataGridView_CellClick End Sub
调整后的GetRecords方法
Private Sub GetRecords() ' 仅保留数据查询和绑定逻辑 Dim query As String = " select distinct t.CPTCode,t.ServiceName,t.DepartmentName,t.SubName,t.Name as Company,t.bedcatename,t.ServiceCharge " & " from tariffpsri t " & " inner join psrirate p on t.Validid= p.Validid " & " inner join ItemOfService i on t.ServiceId = i.ServiceId " & " where t.DepartmentName= @DeptName " & " And t.companyid = 1 And i.Active = 1 " & " And Convert(varchar, p.ValidFrom, 111) = @ValidFrom " & " order by CPTCode " conn = GetConnect() conn.Open() Using cmd As SqlCommand = New SqlCommand(query, conn) cmd.CommandType = CommandType.Text ' 使用参数化查询避免SQL注入 cmd.Parameters.AddWithValue("@DeptName", ComboBox2.Text) cmd.Parameters.AddWithValue("@ValidFrom", ComboBox1.Text) Using sda As SqlDataAdapter = New SqlDataAdapter(cmd) Using dt As DataTable = New DataTable() sda.Fill(dt) ' 绑定前清空原有数据 DataGridView1.DataSource = Nothing DataGridView1.DataSource = dt End Using End Using End Using conn.Close() End Sub
可选适配逻辑
如果你没有在设计器提前配置业务列,需要自动生成查询字段对应的列,可以在绑定数据源前添加以下逻辑:
' 保留第一列CheckBox,清空旧的业务列 While DataGridView1.Columns.Count > 1 DataGridView1.Columns.RemoveAt(1) End While DataGridView1.AutoGenerateColumns = True
你原有的全选和单元格点击逻辑不需要修改,直接保留即可。
内容的提问来源于stack exchange,提问作者gurpreet
相关产品推荐
相关产品推荐

