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

VB.Net:如何将DataGridView选中行数据显示到另一窗体文本框?

问题:DataGridView选中行数据无法传递到编辑窗体的文本框中

我帮你梳理下问题所在,以及对应的解决办法:

核心问题分析

你的代码之所以没效果,主要有两个关键原因:

1. 数据获取的时机不对

你把获取选中行数据的代码放在了CellContentClick事件里,但这个事件只有当你点击DataGridView单元格内的具体内容(比如按钮列的按钮、单元格里的文本)时才会触发。而你的操作流程是先点击选中DataGridView的某一行(可能点击的是行的空白区域或者单元格但没触发CellContentClick),再点击窗体上的编辑按钮——这时候CellContentClick根本没执行,那些公共变量自然都没被赋值,EditPage里当然拿不到数据。

2. 直接访问窗体类的非共享变量存在风险

你在EditPage里用Main.id这种方式访问变量,本质是访问Main窗体类的默认实例。但如果你的Main窗体不是通过默认实例创建的(比如代码里用New Main()打开的),那这个默认实例的变量是空的,和你正在操作的那个Main窗体实例完全不是同一个,自然拿不到正确的数据。


具体解决办法

我推荐两种更可靠的方案,你可以选一种适合自己的:

方案一:用构造函数直接传递数据(最规范的方式)

这种方式不需要公共变量,直接在打开编辑窗体时把选中行的数据传过去,避免全局变量的各种问题:

第一步:给EditPage添加带参数的构造函数

在EditPage.vb里添加以下代码:

' 自定义构造函数,接收选中行的所有数据
Public Sub New(id As Integer, firstname As String, lastname As String, birthdate As String, position As String, sex As String, address As String, contact_num As String, email As String)
    ' 必须先调用InitializeComponent()初始化窗体控件
    InitializeComponent()
    
    ' 直接把数据赋值给对应的控件
    firstname_txtbox.Text = firstname
    lastname_txtbox.Text = lastname
    DateTimePicker1.Text = birthdate
    position_txtbox.Text = position
    sex_combo.Text = sex
    address_txtbox.Text = address
    contact_mask.Text = contact_num
    email_txtbox.Text = email
End Sub

第二步:修改Main窗体的编辑按钮点击事件

在Main.vb的Button3_Click事件里,直接获取选中行数据并传递给EditPage:

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    ' 先判断是否选中了行
    If tblAttendance.CurrentRow Is Nothing Then
        MessageBox.Show("请先选中一行数据再编辑!", "提示")
        Return
    End If
    
    Dim result As Integer = MessageBox.Show("Are you sure you want to Edit the Info?", "Validation", MessageBoxButtons.YesNoCancel)
    If result = DialogResult.Yes Then
        Dim row As DataGridViewRow = tblAttendance.CurrentRow
        Try
            ' 转换并获取每行的数据(注意处理可能的空值)
            Dim id As Integer = If(row.Cells(0).Value Is DBNull.Value, 0, Convert.ToInt32(row.Cells(0).Value))
            Dim firstname As String = If(row.Cells(1).Value Is DBNull.Value, "", row.Cells(1).Value.ToString())
            Dim lastname As String = If(row.Cells(2).Value Is DBNull.Value, "", row.Cells(2).Value.ToString())
            Dim birthdate As String = If(row.Cells(3).Value Is DBNull.Value, "", row.Cells(3).Value.ToString())
            Dim position As String = If(row.Cells(4).Value Is DBNull.Value, "", row.Cells(4).Value.ToString())
            Dim sex As String = If(row.Cells(5).Value Is DBNull.Value, "", row.Cells(5).Value.ToString())
            Dim address As String = If(row.Cells(6).Value Is DBNull.Value, "", row.Cells(6).Value.ToString())
            Dim contact_num As String = If(row.Cells(7).Value Is DBNull.Value, "", row.Cells(7).Value.ToString())
            Dim email As String = If(row.Cells(8).Value Is DBNull.Value, "", row.Cells(8).Value.ToString())
            
            ' 创建EditPage实例并传递数据
            Dim editForm As New Edit_Page(id, firstname, lastname, birthdate, position, sex, address, contact_num, email)
            editForm.Show()
        Catch ex As Exception
            MessageBox.Show("数据转换出错:" & ex.Message, "错误")
        End If
    ElseIf result = DialogResult.No Then
        MessageBox.Show("Edit Cancelled", "Message")
    End If
End Sub

方案二:改进公共变量的使用方式(如果你坚持用公共变量)

如果你还是想用公共变量传递数据,需要修改两个地方:

第一步:把数据获取移到SelectionChanged事件

在Main.vb里添加SelectionChanged事件,确保选中行时就更新公共变量:

Private Sub tblAttendance_SelectionChanged(sender As Object, e As EventArgs) Handles tblAttendance.SelectionChanged
    If tblAttendance.CurrentRow IsNot Nothing Then
        Dim row As DataGridViewRow = tblAttendance.CurrentRow
        Try
            ' 处理空值和类型转换
            id = If(row.Cells(0).Value Is DBNull.Value, 0, Convert.ToInt32(row.Cells(0).Value))
            firstname = If(row.Cells(1).Value Is DBNull.Value, "", row.Cells(1).Value.ToString())
            lastname = If(row.Cells(2).Value Is DBNull.Value, "", row.Cells(2).Value.ToString())
            birthdate = If(row.Cells(3).Value Is DBNull.Value, "", row.Cells(3).Value.ToString())
            position = If(row.Cells(4).Value Is DBNull.Value, "", row.Cells(4).Value.ToString())
            sex = If(row.Cells(5).Value Is DBNull.Value, "", row.Cells(5).Value.ToString())
            address = If(row.Cells(6).Value Is DBNull.Value, "", row.Cells(6).Value.ToString())
            contact_num = If(row.Cells(7).Value Is DBNull.Value, "", row.Cells(7).Value.ToString())
            email = If(row.Cells(8).Value Is DBNull.Value, "", row.Cells(8).Value.ToString())
        Catch ex As Exception
            MessageBox.Show("获取选中行数据失败:" & ex.Message, "错误")
        End If
    End If
End Sub

第二步:传递当前Main窗体实例给EditPage

在EditPage.vb里添加一个属性来接收Main窗体实例:

Public Property ParentMainForm As Main ' 这里的Main是你的Main窗体类名

然后修改EditPage的Load事件:

Private Sub Edit_Page_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    If ParentMainForm IsNot Nothing Then
        ' 通过传递过来的实例访问公共变量
        firstname_txtbox.Text = ParentMainForm.firstname
        lastname_txtbox.Text = ParentMainForm.lastname
        DateTimePicker1.Text = ParentMainForm.birthdate
        position_txtbox.Text = ParentMainForm.position
        sex_combo.Text = ParentMainForm.sex
        address_txtbox.Text = ParentMainForm.address
        contact_mask.Text = ParentMainForm.contact_num
        email_txtbox.Text = ParentMainForm.email
    End If
End Sub

最后修改Main窗体的编辑按钮事件:

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    If tblAttendance.CurrentRow Is Nothing Then
        MessageBox.Show("请先选中一行数据!", "提示")
        Return
    End If
    
    Dim result As Integer = MessageBox.Show("Are you sure you want to Edit the Info?", "Validation", MessageBoxButtons.YesNoCancel)
    If result = DialogResult.Yes Then
        Dim editForm As New Edit_Page()
        editForm.ParentMainForm = Me ' 传递当前Main窗体的实例
        editForm.Show()
    ElseIf result = DialogResult.No Then
        MessageBox.Show("Edit Cancelled", "Message")
    End If
End Sub

额外注意事项

  • 建议把DataGridView的SelectionMode属性设置为FullRowSelect,这样点击行的任何区域都会选中整行,方便获取CurrentRow。
  • 一定要处理单元格值为DBNull的情况,避免空值转换时抛出异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:03:32