在vb.net中使用datagridview从数据库显示数据时出现问题



Im使用vb.net windows窗体、VS 2019、.net框架4.7.2和mysql。

我尝试以一种形式显示数据库中的数据,它运行得很好。

但是,

当我尝试使用相同的过程,在子窗体中使用datagridview显示来自同一数据库的数据时(我通过父窗体调用它,该父窗体将子窗体停靠在父窗体中的一个区域上),它没有显示任何数据,而查询运行得很好,它更新了数据库中的数据,但在这种父子关系的情况下,数据没有显示。

Tho,如果以单独的形式使用,同样的代码也能很好地显示数据

我不知道到底是什么问题。

我必须附上一张以上的图片来解释清楚,所以我上传了它们,链接如下:

https://i.stack.imgur.com/bscbN.jpg

但是,我已经合并了来自不同形式的所有代码片段:

1子类Custom_LoadDataGrid在这里被调用,并且正常工作并在gridview 中显示数据

DB.Custom_LoadDataGrid("SELECT item_name as 'NAME', item_price as 'PRICE', quantity as 'QUANTITY', Amount as 'AMOUNT' FROM transaction WHERE client_name ='" + Label11.Text.ToString + "'")
DB.myConnection.Close()

2在之上调用的子Custom_LoadDataGrid

Public Sub Custom_LoadDataGrid(ByVal search As String)
Try
connString = "server=127.0.0.1;Port=3306;Database=smartcart;Uid=root;Pwd="
myConnection.ConnectionString = connString
myConnection.Open()
sql = search.ToString
DataAdapter = New MySqlDataAdapter(sql, myConnection)
Datacmd = New MySqlCommand(sql, myConnection)
DataAdapter.Fill(DataSet, DbName)
MaxRows = DataSet.Tables(DbName).Rows.Count
Dim dt1 As New DataTable
DataSet.Tables.Add(dt1)
DataAdapter.Fill(dt1)
Portal.Guna2DataGridView1.DataSource = dt1.DefaultView
ReleaseDb()
Catch ex As Exception
MsgBox("Something went wrong")
End Try
End Sub

3我制作了这个子类来调用子窗体并停靠在父窗体中的某个区域

Private Sub OpenChildForm(childForm As Form)
'Open only form'
If currentChildForm IsNot Nothing Then
currentChildForm.Close()
End If
currentChildForm = childForm
'end'
childForm.TopLevel = False
childForm.FormBorderStyle = FormBorderStyle.None
childForm.Dock = DockStyle.Fill
Controls_panel.Controls.Add(childForm)
Controls_panel.Tag = childForm
childForm.BringToFront()
childForm.Show()
End Sub

4这里的子窗体称为

Private Sub Stock_manag_button_Click(sender As Object, e As EventArgs) Handles Stock_manag_button.Click
Sub_menu_panel.Hide()
ActivateButton(sender)
OpenChildForm(New Stock_management)
End Sub

5这个子类Custom_Load_DataGrid在这里被调用,但没有在gridview 中显示数据

DB.Custom_Load_DataGrid("SELECT * FROM addition_stock ")
DB.myConnection.Close()

'6子类Custom_Load_DataGrid与Custom_LoadDataGrid完全相同(但显然具有不同的变量和相关表单名称)但这并不是在gridview中显示数据,只是在这种父子窗体的情况下,尽管这种窗体在用于分隔时也很好表格。

Public Sub Custom_Load_DataGrid(ByVal search As String)
Try
connString = "server=127.0.0.1;Port=3306;Database=smartcart;Uid=root;Pwd="
myConnection.ConnectionString = connString
myConnection.Open()
sql = search.ToString
DataAdapter = New MySqlDataAdapter(sql, myConnection)
Datacmd = New MySqlCommand(sql, myConnection)
DataAdapter.Fill(DataSet, DbName)
MaxRows = DataSet.Tables(DbName).Rows.Count
MsgBox(MaxRows.ToString)
Dim dt2 As New DataTable
DataSet.Tables.Add(dt2)
DataAdapter.Fill(dt2)
Stock_addition.Guna2DataGridView1.DataSource = dt2.DefaultView
ReleaseDb()
Catch ex As Exception
MsgBox("Something went wrong")
End Try
End Sub

我能让你在一个新项目中做这件事吗?作为一个迷你教程,让你的生活更轻松:

  • 创建一个新项目
  • 添加表单
  • 添加数据集
  • 打开数据集,右键单击曲面并添加表适配器
  • 创建一个连接字符串以存储在设置中:选择mysql连接器(注意,要实现这一点,您需要mysql连接器,也需要visualstudio的mysqlhttps://dev.mysql.com/downloads/windows/visualstudio/),并填写详细信息以创建数据库连接字符串,确保测试连接成功
  • 继续执行向导,选择"返回行的查询","通过sql",输入SELECT * FROM addition_stock WHERE ID = @id的查询
  • 写入FillByID和GetDataByID的名称
  • 饰面

您将看到一个看起来像数据库表的东西出现,下面有一个名为addition_stockTableAdapter的东西

  • 右键单击表适配器,选择添加。。查询
  • 添加另一个与如何搜索此表更相关的查询,例如SELECT * FROM addition_stock WHERE stock_code = @stockCode
  • 称之为FillByStockCode/GetDataByStockCode
  • 始终为填充/获取数据方法提供相关名称

始终将创建数据表/表适配器对的第一个查询设为"select where id="-这会使以后的操作更容易。添加需要的任意多个附加查询

这次对addition_stock的父表或子表再做同样的事情(添加表适配器)——不管是哪一个,我只是想在这里演示一下。确保使用数据库中有外键的表来添加_库存

一旦您添加了与addition_stock相关的另一个数据表/表适配器对,您将看到一行连接两个数据表

  • 右键单击此行并选择"显示关系标签"以显示关系的名称-它来自数据库中的外键

现在我们将添加一种方便的方法来加载基于父id 的子数据

  • 右键单击子表适配器并选择"添加查询">
  • 添加一个SELECT * FROM tablenamehere WHERE parentidcolumnnamehere = @parentid的查询,并将其称为合适的FillByXxx-显然,用实际值替换表名、列名和xxx

  • 保存数据集并切换到表单设计器

  • 显示"数据源"窗口(视图菜单..其他窗口)
  • 展开数据集的所有节点-您将看到一个父表和两个子表,一个子表在父表下面,另一个子表不在
  • 将父表从数据源中拖到窗体上-将显示一个带列的数据网格视图,底部托盘中的表适配器、bindingnavigator、DataSet和bindingsource也将出现。导航有一个文本框,你可以在其中写入id,还有一个按钮可以按下。datagridview列被适当地设置,并且网格被绑定到bindingsource。绑定源已绑定到数据集父表
  • 运行该应用程序,在文本框中输入一个ID,单击fill,编辑某个东西的名称,单击save,使用mysql工作台查找数据库。超级的你可以下载、编辑和保存数据库数据,而且你还没有写过一行代码;您只是在使用visualstudio为您编写的数千行代码
  • 停止应用程序,返回表单设计器
  • 将父表下面的子表拖到窗体上。会出现更多项-绑定到另一个绑定源的数据网格视图、另一个导航器等。您可以删除第二个导航器-我们不会使用它
  • 查看子表的绑定源-请注意,它没有直接绑定到DataSet,而是绑定到另一个绑定源,其中DataMember属性设置为两个表之间关系行的名称
  • 切换到代码视图,查看Fill toolstrip菜单中的代码,该菜单通过id/whathing填充父记录。如果子bindingnavigator中有任何多余的代码,请将其删除(或注释掉:这可能对下一步稍微有用
  • 在按id填充父数据表的代码行下,放入以下代码:

    childTableAdapter。ClearBeforeFill=错误您的数据集名称。ChildTableName。清除()对于您的DataSetName中的每个parentRow。YourParentTableNamechildTableAdapter。FillByParentId(您的DataSetName.ChildTableName,parentRow.Id)下一个

再次运行应用程序,输入父id,单击填充。加载父数据和相关的子数据。很好,但当我们加载多个父行时,真正的神奇之处就发生了。返回到代码并将父表适配器上的FillById替换为您编写的另一个查询(如果您没有执行此操作,请返回到DataSet,向加载多行的父表适配器添加一个查询,如select * from person where lastname = @lastname,这样我们就可以输入smith这样的姓氏,其中有很多),所以现在您的代码在填充中如下所示:

parentTableAdapter.FillBySonethingThatGetsMultipleRows(yourDataSetName.ParentTableName, fillByTextboxName.Text)
childTableAdapter.ClearBeforeFill = False
yourDatasetName.ChildTableName.Clear()
For Each parentRow in yourDataSetName.YourParentTableName
childTableAdapter.FillByParentId(yourDataSetName.ChildTableName, parentRow.Id)
Next

你会注意到,你会得到多个父行,你会在循环中加载多组子行,但当你运行应用程序并在父网格中选择不同的父行时,子网格会自动过滤,只显示当前选择的父的子行

最新更新