具有来自数据库的值的组合框不会显示从 Datagridview 行传递的值,即使这些值相同

Combobox with values from database won't display passed value from Datagridview row even if the values are the same

我的表单中有一个 Combobox1,它加载了数据库中的值。这些值完美加载到 Combobox1 中。在更新学生信息的过程中,我在 datagridview 中有一行有一个按钮“编辑”,当我单击“编辑”按钮时,它会显示一个带有文本框和组合框的表单,其中加载了所有值来自 Datagridview 行,与该特定学生有关。在表单加载事件中,我将数据从数据库加载到 Combobox1。当表单显示时,Combobox1 显示数据库查询中的第一个项目,而不是我选择传递给 Combobox1 的 Datagridview 中的值,即使它们与查询中的项目相同。

这是获取数据的代码

 Public Sub LoadSections(cb As ComboBox)

        Try
            sql = "SELECT ID, section_name FROM slm_sections WHERE school_id = @SCHOOLID ORDER BY section_name ASC"
            dbconnect()
            conn.Open()

            cmd = New MySqlCommand(sql, conn)
            cmd.Parameters.AddWithValue("@SCHOOLID", My.Settings.SchoolID)

            Dim adptr As New MySqlDataAdapter(cmd)
            Dim table As New DataTable()

            adptr.Fill(table)
            cb.DataSource = New BindingSource(table, Nothing)
            cb.DisplayMember = "section_name"
            cb.ValueMember = "ID"

            cmd.Dispose()
            adptr.Dispose()
            conn.Close()

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

将值从 datagridview 传递到 Combobox1,这是我的代码

            Dim frm2 As New FormAddNewStudent
            With frm2

                frm2.Text = "Update Student Info"

                LoadGradeLevels(.CbGradeLevel)
                LoadSections(.CbSection)
                LoadStrands(.CbStrand)

                .TxtLastName.Text = StudentList.SelectedCells(5).Value.ToString
                .TxtFirstName.Text = StudentList.SelectedCells(6).Value.ToString
                .TxtMiddleName.Text = StudentList.SelectedCells(7).Value.ToString

                .TxtLRN.Text = StudentList.SelectedCells(8).Value.ToString

                .CbGender.SelectedItem = StudentList.SelectedCells(9).Value.ToString
                .CbGradeLevel.SelectedItem = StudentList.SelectedCells(10).Value.ToString
                .CbSection.SelectedItem = StudentList.SelectedCells(11).Value.ToString
                .CbStrand.SelectedItem = StudentList.SelectedCells(12).Value.ToString
                .BtnSave.Text = "Update"



            End With
            frm2.ShowDialog()

Studentlist 是 Datagridview,StudentList.SelectedCells(1).Value.ToString 是我需要加载到 Combobox1 的数据。

一直到您开始使用 DataGridView 中选定的单元格集合从 DataGridView 中挖掘数据时,一切进展顺利 - 此时“代码正在使用数据绑定;它通过数据模型执行数据操作”崩溃了。

我认为最简单的做法是在您的编辑表单上安排所有控件,以便它们绑定到相同的绑定源 X,然后将网格绑定到的绑定源 Y 传递给第二个表单并将 X 绑定到 Y。图形上我们将安排的内容如下所示:

主窗体会有一个grid,绑定一个BS,绑定一个datatable。第二个窗体将控件绑定到一个 BS,该 BS 绑定到主窗体的 BS。编辑表单上的组合从单独的数据源获取其列表项,并使用它们来更改主 table

中学生部分的 ID

编写绑定代码是重复性的而且相当无聊,所以我将快速介绍一下如何让 windows 表单设计器来完成它,并且我会加入一些让您可以编写的代码SQLs/getting 将 of/saving 内容输出到数据库也更容易:

(提前注意,这里的过程只能在 .net 框架上正常工作;如果你的项目是 .net 核心,你会很困难,因为数据绑定设计在 net 核心+ 中非常 broken/incomplete)

  • 向项目添加 DataSet 类型的文件
  • 打开它,右键单击表面并选择添加 TableAdapter
  • 设置连接字符串,放置提取学生数据的查询,完成向导。从现在开始,我将把它称为“学生”数据table(我不知道它在你的数据库中叫什么)
  • 再次右击surface,Add TableAdapter,同样的conn str,查询SELECT ID, section_name FROM slm_sections WHERE school_id = @SCHOOLID ORDER BY section_name ASC完成。我将把它称为 Sections datatable
  • 转到一个新表单(以避免干扰您现有的代码)并打开数据源 window(查看菜单,其他 windows)
  • 将学生节点拖到窗体中。有些东西出现在托盘、页眉和表格的网格中
  • 制作新表格
  • 在数据源中放下学生节点并将其从网格更改为详细信息
  • 将部分(在学生下)从文本框更改为组合框
  • 将Student节点拖到窗体上,出现多个控件都绑定到同一个bindingsource
  • 将 Section 节点拖到表单中,但删除它制作的网格 - 我们不需要它,但我们确实需要它制作的其他一些东西
  • 关于组合:
    • 将数据源设置为 SectionBindingSource
    • 适当设置Display/Value成员
    • 展开属性网格顶部的 (DataBindings) 并查看为 Text 绑定的内容 - 在 SelectedValue 中设置 相同的内容 然后右键单击 Text 并选择 Reset (文本绑定错误,需要是绑定到 Students.SectionID)
    • 的 SelectedValue
  • 转到此表单的代码视图 2
  • 删除 Load 事件中的填充代码 - 我们不需要它们,因为我们将重复使用主窗体下载的数据
  • 将我们可以发送 BindingSource 的构造函数放入:
    Public Sub New(toUse As BindingSource)

        InitializeComponent()

        StudentsBindingSource.DataMember = Nothing
        StudentsBindingSource.DataSource = toUse
    End Sub
  • 在主窗体中更改显示编辑窗体的代码,以便它将 StudentBindingSource 从主窗体发送到编辑窗体:
    Dim f as New ...WhateverForm(StudentsBindingSource) 
    f.Show()

编辑表单将接收绑定源并将其自己的绑定源绑定到它,将两者链接在一起。这意味着编辑表单上的控件会将数据 from/push 数据读入主表单的 dataset/datatable/bindingsource 表单中,因此网格和控件都从单一数据源读取和编辑


现在,您不必做所有这些,制作数据集和 table 适配器 - 绑定部分不依赖于这些,只是通过从数据源拖放来编写绑定代码 window 很简单

你可以看看上面建议的后半部分,在接受 BS 的 eidt 表单中创建一个构造函数,传递一个 BS,然后在该构造函数中你可以将编辑表单的 Section 组合设置为具有绑定如:

Me.SectionComboBox.DataBindings.Add(New Binding("SelectedValue", toUse, "SectionId", True))

加上将其他内容 (datasource/disp/val) 设置为现有数据列表(您清楚地知道如何从数据库中获取某些部分),这意味着编辑表单的组合将直接绑定到 BS主要形式。它们是链式的还是直接的都无关紧要;我将它们与表单设计者创建的东西链接起来,因为它比将表单上的每个控件重新绑定到从 main

传递的 toUse 绑定源更容易