【问题标题】:vb.net working with multiple controls added at runtimevb.net 使用在运行时添加的多个控件
【发布时间】:2012-09-21 21:07:27
【问题描述】:

我正在为数据表中的每条记录添加一个选项卡页和 datagridview 到选项卡控件。

我想为每条记录创建一个新的 Tab/DataGridView(现在大约有 3 个)。我在声明一个新的DataGridView D。我以后如何引用这些控件?

我想做一些事情,比如将 datagridview 中的更改保存到数据库中。目前我可以在屏幕上获取数据并且看起来不错,但我认为我没有正确添加 DataGridView 控件,因为我一直在重复使用“D”作为控件。

            Dim dt As New DataTable

        GetDataTable("SELECT * FROM aFeeTypes DescSeq", dt)

        Dim i As Integer

        'for each class in the datatable add a tab and a datagridview
        For i = 0 To dt.Rows.Count - 1

            Dim dr As DataRow
            dr = dt.Rows(i)

            Dim D = New DataGridView
            D.Visible = True

            Dim tp As New TabPage
            tp.Name = "tp" & i
            tp.Text = dr.Item("Desc2")
            frmUI.tcFee.TabPages.Add(tp)
            frmUI.tcFee.TabPages(i).Controls.Add(D)

            dgv_Fill(D, "SELECT * FROM Fee WHERE ClassID=" & dr.Item("ClassID") & " ORDER BY Seq")

            D.AutoResizeColumns()
            D.Width = tp.Width
            D.Height = tp.Height

        Next i

这不起作用:

            With frmUI.Controls("D" & i)
                .AutoResizeColumns()
                .Width = tp.Width
                .Height = tp.Height
            End With

【问题讨论】:

    标签: vb.net controls runtime naming


    【解决方案1】:

    D 纯粹是你使用它的作用域中的变量名。

    您需要为控件提供一个唯一的Name,以便以后引用它。

    Name 属性可用于在运行时通过以下方式评估对象 名称而不是类型和程序名称。因为 Name 属性 返回一个 String 类型,它可以在 case-style 逻辑中进行评估 语句(Visual Basic 中的 Select 语句, Visual C# 和 Visual C++)。

    【讨论】:

    • 我尝试添加 D.Name = "D" & i 但是如何在 IDE 中使用该名称而不是对象?
    • 运行时意味着您不会在 IDE 中看到它。也许再解释一下你的意图是什么,我们可以看看。
    • 当我在设计时添加一个控件时,我知道它的名称并且可以在 IDE 中设置它的属性。在这种情况下,我在运行时添加了多个控件,如果我想引用添加的第二个 DataGridView,我该怎么做?我正在考虑一个带有 D(1)、D(2) 等的控制数组
    • 我认为我错过了 OOP 的“大局”。
    • 如果您希望在以后的某个阶段引用控件,您将不得不引用 Form.Comtrols 集合(请记住,这可以递归完成)或一些存储的控件列表。
    【解决方案2】:

    我找到了解决问题的方法。问题是新行有一个自动编号 ID。

    当 da.update(dt) 发生时,新行被插入到数据库中。数据库知道新的自动编号 ID。但是,数据表没有。

    为了让数据表知道,数据适配器被重新填充。但是,这会导致数据表包含所有旧行和所有新行,并且它们都出现在 datagridview 中。

    通过清除数据表中的旧行,填充刷新了数据表中的所有数据,从而刷新了datagridview。

        Public Sub dgv_AddRow(ByVal dgvName As String)
    
        Dim dgv As DataGridView = colDataGridView.Item(dgvName)
    
        Dim da As SqlDataAdapter = colDataAdapter.Item(dgvName)
        Dim dr As DataRow = frmUI.allDataSet.Tables(dgvName).NewRow
    
        'autopopulate the class id
        dr("ClassID") = dgv.Parent.Tag
    
        'add the new row
        frmUI.allDataSet.Tables(dgvName).Rows.Add(dr)
    
        'get the changed table
        Dim dt As DataTable = frmUI.allDataSet.Tables(dgvName)
    
        'inserts the new row to the database.  concurrency violation 
        'will occur because datatable does not know the new Autonumber ID for the new row.
    
        da.Update(dt)
    
        'remove the datatable rows so they can be replaced using the adapter fill
        'if rows are not cleared, following fill causes datatable to 
        'have existing rows plus all the rows again due to the fill
    
        frmUI.allDataSet.Tables(dgvName).Rows.Clear()
    
        'refill the adapter (refill the table)
        'Everything you do to the underlying dataTable
        'gets displayed instantly on the datagridview
    
        da.Fill(frmUI.allDataSet, dgvName)
    
    
    
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2011-07-26
      • 1970-01-01
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多