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

VB.NET中使用BindingSource增删改后维持DataGridView选中行求助

问题描述

在VB.NET中使用BindingSource对DataGridView控件执行插入、更新和删除操作后,无法维持选中行的状态,具体现象:

  • 插入记录后,选中行自动跳转到新记录位置
  • 更新记录后,选中行自动跳转到被更新的记录位置
  • 删除记录后,选中行跳转到被删除记录的上一条记录

已尝试使用DataGridView的DataBindingComplete事件,但未生效,现有代码及修改后的解决方案如下:


解决方案

核心问题在于每次操作后重建BindingSource导致状态丢失,以及选中状态保存逻辑缺失,以下是具体修改方案:

关键修改点

  1. 复用BindingSource,避免每次操作重建控件绑定
  2. 保存记录的唯一ID作为选中标识(而非可能重复的CatProd字段)
  3. 在增删改操作前保存当前选中状态,重新绑定后定位回目标行
  4. 修正DataBindingComplete事件的触发逻辑,确保状态恢复生效

修改后的完整代码

Dim CatProdService As New CatProdService()
Private bindingSource As BindingSource = Nothing
Private selectedID As Integer? ' 保存选中记录的唯一ID
Private selectedIndex As Integer

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    LoadData1()
End Sub

Private Sub LoadData1()
    Dim CatProdList = CatProdService.Getitem()
    ' 复用BindingSource,仅更新数据源而非重建
    If bindingSource Is Nothing Then
        bindingSource = New BindingSource()
        DataGridView1.DataSource = bindingSource
        DataGridView1.ReadOnly = True
    End If
    bindingSource.DataSource = New BindingList(Of CatProd)(CType(CatProdList, IList(Of CatProd)))
End Sub

Private Function GetSELECT() As CatProd
    Return If(DataGridView1.SelectedCells.Count = 0, Nothing, TryCast(DataGridView1.SelectedCells(0).OwningRow.DataBoundItem, CatProd))
End Function    

Private Sub DataGridView1_DataBindingComplete(sender As Object, e As DataGridViewBindingCompleteEventArgs) Handles DataGridView1.DataBindingComplete
    ' 有保存的选中ID时,尝试定位回目标行
    If selectedID.HasValue AndAlso bindingSource.List.Count > 0 Then
        selectedIndex = bindingSource.Find("ID", selectedID.Value)
        ' 找不到目标行(如已删除)则选中第一条记录
        selectedIndex = If(selectedIndex >= 0, selectedIndex, 0)
        If selectedIndex >= 0 Then
            DataGridView1.Rows(selectedIndex).Selected = True
            DataGridView1.FirstDisplayedScrollingRowIndex = selectedIndex ' 确保选中行可见
        End If
    End If
End Sub

Private Sub BtnDelete_Click(sender As Object, e As EventArgs) Handles BtnDelete.Click
    Try
        Dim SelectDgv = GetSELECT()
        If SelectDgv Is Nothing Then
            MessageBox.Show("请先选择一条记录", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Return
        End If
        ' 删除前保存选中ID
        selectedID = SelectDgv.ID
        If MessageBox.Show("确定删除选中记录?", "确认", MessageBoxButtons.YesNoCancel) = DialogResult.Yes Then
            CatProdService.DeleteItem(SelectDgv.ID)
            LoadData1()
            ' 删除后若找不到原ID,重置选中第一条记录
            If bindingSource.Find("ID", selectedID.Value) < 0 Then
                selectedID = If(bindingSource.List.Count > 0, DirectCast(bindingSource.List(0), CatProd).ID, Nothing)
            End If
        End If
    Catch ex As Exception
        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Try
End Sub

Private Sub Btnsave_Click(sender As Object, e As EventArgs) Handles Btnsave.Click
    Dim CatProd = CatProdService.GetByCatProd(txtCatProd.Text)
    Dim DesCatProd = CatProdService.GetByDesCatProd(txtDesCatProd.Text)
    Dim idValue As Integer
    ' 修正ID类型转换错误(原代码用Boolean.TryParse逻辑错误)
    Dim isValidID = Integer.TryParse(btxtid.Text, idValue)

    Dim userid2 = CatProdService.GetCatProdById2(idValue)
    Try
        If txtCatProd.TextLength > 3 Then
            MessageBox.Show("CatProd只能输入3个字符或数字")
            Return
        End If
        If userid2 Is Nothing Then
            ' 插入逻辑:保存当前选中状态
            Dim currentSelected = GetSELECT()
            selectedID = If(currentSelected IsNot Nothing, currentSelected.ID, Nothing)
            
            If CatProd IsNot Nothing Then
                MessageBox.Show("CatProd已存在")
                Return
            End If
            If DesCatProd IsNot Nothing Then
                MessageBox.Show("DesCatProd已存在")
                Return
            End If
            If String.IsNullOrEmpty(txtCatProd.Text) OrElse String.IsNullOrEmpty(txtDesCatProd.Text) Then
                MessageBox.Show("请填写CatProd和DesCatProd", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Return
            End If
            
            CatProdService.InsertCatProd(New CatProd() With {
                .CatProd = txtCatProd.Text,
                .DesCatProd = txtDesCatProd.Text
            })
        Else
            ' 更新逻辑:保存被更新记录的ID
            selectedID = userid2.ID
            CatProdService.UpdateCatProd(New CatProd() With {
                 .CatProd = txtCatProd.Text,
                .DesCatProd = txtDesCatProd.Text,
                .ID = idValue
             })
        End If
        MessageBox.Show("操作成功")
        LoadData1()
    Catch ex As Exception
        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Try
End Sub

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:47:31