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

如何在Visual Basic 2015中通过两个窗体刷新DataGridView?

解决跨窗体DataGridView刷新问题(VB.NET)

首先,先帮你修正frmAddBooks里的插入代码——你现在同时混用了字符串拼接SQL和参数化查询,这是错误的,既容易引发SQL注入风险,也没真正发挥参数化查询的作用。先把这部分改对:

Imports System.Data.OleDb
Public Class frmAddBooks
    ' 定义事件:当书籍添加成功时触发
    Public Event BookAddedSuccessfully()

    Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
        Dim cn As New OleDbConnection
        Dim cm As New OleDbCommand
        Try
            With cn
                .ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\Assessment of the CKC Library System\Database.accdb"
                .Open()
            End With
            With cm
                .Connection = cn
                .CommandType = CommandType.Text
                ' 使用参数占位符替代字符串拼接,彻底避免SQL注入
                .CommandText = "INSERT INTO [Books] ([ISBN],[BookTitle],[Author],[Category],[Foreword],[YearPublished], [Quantity]) VALUES (@ISBN, @BookTitle, @Author, @Category, @Foreword, @YearPublished, @Quantity)"
                ' 正确添加参数并赋值
                .Parameters.Add(New OleDbParameter("@ISBN", OleDbType.VarChar, 30)).Value = Me.txtISBN.Text
                .Parameters.Add(New OleDbParameter("@BookTitle", OleDbType.VarChar, 255)).Value = Me.txtBookTitle.Text
                .Parameters.Add(New OleDbParameter("@Author", OleDbType.VarChar, 255)).Value = Me.txtAuthor.Text
                .Parameters.Add(New OleDbParameter("@Category", OleDbType.VarChar, 255)).Value = Me.cboCategory.Text
                .Parameters.Add(New OleDbParameter("@Foreword", OleDbType.VarChar, 255)).Value = Me.txtForeword.Text
                .Parameters.Add(New OleDbParameter("@YearPublished", OleDbType.VarChar, 255)).Value = Me.cboYearPublished.Text
                .Parameters.Add(New OleDbParameter("@Quantity", OleDbType.VarChar, 255)).Value = Me.cboQuantity.Text
                
                cm.ExecuteNonQuery()
                MsgBox("Book added.", MsgBoxStyle.Information, "Saved Successfully!")
                
                ' 清空输入框
                Me.txtISBN.Text = ""
                Me.txtBookTitle.Text = ""
                Me.txtAuthor.Text = ""
                Me.txtForeword.Text = ""
                cboCategory.SelectedIndex = -1
                cboQuantity.SelectedIndex = -1
                cboYearPublished.SelectedIndex = -1
                
                ' 触发书籍添加成功事件
                RaiseEvent BookAddedSuccessfully()
            End With
        Catch ex As Exception
            MsgBox($"Error: {ex.Message}", MsgBoxStyle.Exclamation, "Error")
        Finally
            ' 确保数据库连接关闭并释放资源
            If cn.State = ConnectionState.Open Then
                cn.Close()
            End If
            cn.Dispose()
            cm.Dispose()
        End Try
    End Sub

    Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
        Hide()
    End Sub
End Class

接下来解决跨窗体刷新的核心问题——你之前的frmSearchUpdateBooks用DataSet缓存了数据,添加新数据后没有重新从数据库拉取最新内容,所以DataGridView显示旧数据。这里给你两种简单易上手的方案:


方案一:通过事件通知刷新(推荐,低耦合)

这种方法符合面向对象设计,两个窗体之间通过事件通信,耦合度低,适合长期维护。

在frmSearchUpdateBooks中,打开frmAddBooks时订阅它的BookAddedSuccessfully事件,事件触发时重新填充DataGridView:

Public Class frmSearchUpdateBooks
    ' 保存添加窗体的实例
    Private addBookForm As frmAddBooks

    Private Sub frmSearchUpdateBooks_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.BooksTableAdapter.Fill(Me.DatabaseDataSet.Books)
        ' 初始化添加窗体并订阅事件
        addBookForm = New frmAddBooks
        AddHandler addBookForm.BookAddedSuccessfully, AddressOf RefreshBookData
    End Sub

    ' 封装刷新数据的方法
    Private Sub RefreshBookData()
        Me.DatabaseDataSet.Books.Clear() ' 清空旧数据
        Me.BooksTableAdapter.Fill(Me.DatabaseDataSet.Books) ' 拉取最新数据
        Me.DataGridView1.Refresh()
    End Sub

    ' 假设你有打开添加窗体的按钮,比如btnAddBook_Click
    Private Sub btnAddBook_Click(sender As Object, e As EventArgs) Handles btnAddBook.Click
        addBookForm.Show()
    End Sub

    ' 保留你原有的其他方法
    Private Sub BooksBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs)
        Me.Validate()
        Me.BooksBindingSource.EndEdit()
        Me.TableAdapterManager.UpdateAll(Me.DatabaseDataSet)
    End Sub

    Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
        Try
            BooksBindingSource.EndEdit()
            BooksTableAdapter.Update(DatabaseDataSet)
            MsgBox("Successfully saved.", MsgBoxStyle.OkOnly, "Success!")
            RefreshBookData() ' 保存后也可调用刷新
        Catch ex As Exception
            MsgBox("Please fill all the information needed. If all informations are filled up, please re-check the ISBN as some book might have the same ISBN as you are entering.", MsgBoxStyle.OkOnly, "Error!")
        End Try
    End Sub

    Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
        BooksBindingSource.RemoveCurrent()
        BooksBindingSource.EndEdit()
        MsgBox("Item successfully deleted!", MsgBoxStyle.OkOnly, "Success!")
    End Sub

    Private Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
        Try
            Me.Validate()
            Me.BooksBindingSource.EndEdit()
            Me.BooksTableAdapter.Update(DatabaseDataSet)
            MsgBox("Updated Successfully!", MsgBoxStyle.OkOnly, "Update Successful!")
        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            RefreshBookData()
        End Try
    End Sub
End Class

方案二:直接查找已打开的窗体实例刷新(简单直接)

如果frmSearchUpdateBooks是始终处于打开状态的,可以在frmAddBooks保存成功后直接找到它的实例并调用刷新方法:

首先在frmSearchUpdateBooks中添加一个公共的刷新方法:

Public Sub RefreshBookData()
    Me.DatabaseDataSet.Books.Clear()
    Me.BooksTableAdapter.Fill(Me.DatabaseDataSet.Books)
    Me.DataGridView1.Refresh()
End Sub

然后在frmAddBooks的btnSave_Click方法中,保存成功后添加以下代码:

' 查找已打开的frmSearchUpdateBooks实例
Dim searchForm As frmSearchUpdateBooks = Application.OpenForms.OfType(Of frmSearchUpdateBooks)().FirstOrDefault()
If searchForm IsNot Nothing Then
    searchForm.RefreshBookData()
End If

这种方法更直接,但两个窗体的耦合度较高,适合简单场景。


关键总结:

  • 问题核心:frmSearchUpdateBooks的DataSet没有重新从数据库读取最新数据,只要在添加成功后重新执行BooksTableAdapter.Fill就能刷新DataGridView。
  • 一定要修正参数化查询的问题,字符串拼接SQL不仅容易出错,还存在严重的安全风险。

内容的提问来源于stack exchange,提问作者Rey Anthony Abarquez Rosalado

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:30:45