Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 每次调用ShowDialog时删除控件_Vb.net_Showdialog_Control Array - Fatal编程技术网

Vb.net 每次调用ShowDialog时删除控件

Vb.net 每次调用ShowDialog时删除控件,vb.net,showdialog,control-array,Vb.net,Showdialog,Control Array,我有一个表单,我只使用ShowDialog方法显示它。在显示的Form_事件中,我根据调用表单中设置的公共变量动态创建了一组标签和文本框 我知道表单没有关闭或销毁,只是隐藏在调用之间,因此我在我的form\u show事件顶部添加了代码,以清除以前调用中的任何控件,但这些控件没有被删除。我已经尝试了ctrl.Dispose(如下代码所示)和Me.Controls.Remove(ctrl)。两者都不会产生错误,但不会删除文本框,并在其上创建新的文本框。(由于某种原因 这是我第一次在.NET中动态创

我有一个表单,我只使用
ShowDialog
方法显示它。在显示的
Form_
事件中,我根据调用表单中设置的公共变量动态创建了一组标签和文本框

我知道表单没有关闭或销毁,只是隐藏在调用之间,因此我在我的
form\u show
事件顶部添加了代码,以清除以前调用中的任何控件,但这些控件没有被删除。我已经尝试了
ctrl.Dispose
(如下代码所示)和
Me.Controls.Remove(ctrl)
。两者都不会产生错误,但不会删除文本框,并在其上创建新的文本框。(由于某种原因

这是我第一次在.NET中动态创建/删除控件,因此我对VB6控件数组的渴望可能与错误有关

表单基于调用表单的公共ListView变量构建自身。调用表单确保此变量不是空变量,并且仅当用户正在编辑现有行时才选择项目

Public Class frmTableEdit

Private isNew As Boolean
Private inputText() As TextBox

Private Sub FormTableEdit_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    For Each ctrl As Control In Me.Controls
        If TypeOf (ctrl) Is TextBox Or TypeOf (ctrl) Is Label Then
            ctrl.Dispose()
        End If
    Next
    With frmKioskData.TBLobj
        Dim fieldCount As Integer = .Columns.Count - 1
        isNew = .SelectedIndices.Count = 0

        '(code setting size of form and location of OK/Cancel buttons is here)

        ReDim inputText(fieldCount)
        For i As Integer = 0 To fieldCount
            Dim lbl As New Label, txt As New TextBox
            inputText(i) = txt
            Me.Controls.Add(lbl)
            Me.Controls.Add(txt)

            '(code setting size and and position of lbl & txt is here)

            'lbl.Tag = i    (I commented these lines out because I never used the 
            'txt.Tag = i    Tag property, but can if a solution calls for it.)

            lbl.Text = .Columns(i).Text
            If isNew Then
                txt.Text = ""
            Else
                txt.Text = .Items(.SelectedIndices(0)).SubItems(i).Text
            End If
        Next
    End With
End Sub

End Class

如果@puropoix在上述评论中的建议对您不太合适,我认为在调用ShowDialog后处理表单是最简单和更有意义的,然后当您需要显示该表单时,您可以创建一个新实例,其中包含一个参数,告诉它要加载哪些动态控件

因此,在frmTableEdit中有一个新方法使用此参数:

Public Sub New(ByVal fieldCount As Integer)
        InitializeComponent()
        fieldCount = fieldCount  'Where fieldCount is a class variable
End Sub
当您从frmKioskData调用此表单时,您可以这样做:

Dim newTableEdit As New frmTableEdit(Me.TBLobj.Columns.Count - 1)
newTableEdit.ShowDialog()
newTableEdit.Dispose()
然后,frmEditTable的显示事件中的代码只需相应地添加控件,而无需删除旧控件:

ReDim inputText(fieldCount)
For i As Integer = 0 To fieldCount
    Dim lbl As New Label, txt As New TextBox
    inputText(i) = txt
    Me.Controls.Add(lbl)
    Me.Controls.Add(txt)

    '(code setting size and and position of lbl & txt is here)

    'lbl.Tag = i    (I commented these lines out because I never used the 
    'txt.Tag = i    Tag property, but can if a solution calls for it.)

    lbl.Text = .Columns(i).Text
    If isNew Then
        txt.Text = ""
    Else
        txt.Text = .Items(.SelectedIndices(0)).SubItems(i).Text
    End If
Next

如何获取isNew值取决于您-您可以将其作为第二个参数添加到表单的新参数中,或者以与现在相同的方式获取它…w/e。如果是我,我通常会将其作为另一个新参数添加。

您可能会弄乱默认实例。为什么顶部循环使用
me
但稍后您会使用
frmKioskData
ar它们是相同的东西吗?显示对话框的代码可能会有帮助。@puropoix,它们不一样;
frmKioskData
是调用表单。我现在不在电脑前获取确切的代码,但我可以告诉你我使用的是
frmTableEdit.ShowDialog()
而不是将变量声明为新表单。我通过调试知道,无论这是否为默认值,每次调用都会得到相同的实例(如预期的那样),并且每次都会触发显示的
事件(也如预期的那样)。我怀疑问题出在
Dispose
上,因为
Me.Controls.Count
会随着每次连续调用而增加。
inputText()的用途是什么
array?存储对文本框控件的附加引用将阻止它们被处理。如果使用显式表单引用并将处理循环放入
Sub-Dispose(bool disposing)
中,它们应该很好地清理
inputText()
的存在使我可以在单独的事件中按索引引用每个文本框。但是感谢您提供有关额外引用阻止处置@puropoix的提示;我不知道这一点(尽管现在看起来很明显)我强烈怀疑这就是我的问题的原因。我会在早上更新。你不需要一个控件引用数组,只需要
列表(字符串)
中的控件名称给它们命名,比如
“tbNumber”&I.ToString()
并在控件集合中使用名称引用它们。这种通用方法对我有效。在释放额外的引用(
inputText
)后,我仍然存在同样的问题。在稍微调整后(主要是因为我的代码需要整个
ListView
对象,而不仅仅是
列。Count
),一切正常。