2014-12-07 90 views
0

我想了解更多关于VB.NET和多个窗体,所以我可以让我的代码更好。窗体内的窗体上的文本框不更新

我有一个SQL数据库表,它包含所有14个进程的实时数据,监视程序更新显示所有进程进度的窗体。多年前在MS Access中,我只是简单地使用滚动子窗体来显示表格的内容。然而,我第一次尝试在VB.NET中是有“很多”文本框,基本上14行文本框,我的代码有14个非常相似的部分更新所有的文本框。必须有一个更好的办法:(

例如:

txtProcessID1.Text TxtStatus1.Text ProgressBar1 ......

txtProcessID2.Text TxtStatus2.Text ProgressBar2 ......

txtProcessID3.Text TxtStatus3.Text ProgressBar3 ......

所以,我想拿出我在那里创建子窗体,看起来像一个控制器行代码,然后创建的14个实例在我的mainform上的这个子表格。

我的测试代码似乎工作,但子窗体上的文本框没有更新屏幕上的内容!即使当我回拨.text的内容时,这也是我所期望的。

为什么此示例代码不起作用,而我的解决方案是完成此操作的最佳方式?

Public Class MainForm 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     SubForm.SetText = Me.TextBox1.Text ' Try to change contents of a TextBox on the SubForm 
     Me.TextBox2.Text = SubForm.SetText ' Data comes back as expected, but the subform textbox remains unchanged. 
    End Sub 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     Dim objSubForm As New SubForm() 
     objSubForm.TopLevel = False 
     Me.Panel1.Controls.Add(objSubForm) 
     objSubForm.Show() 
    End Sub 
End Class 

Public Class SubForm 
    Public Property SetText() As String 
     Get 
      SetText = TextBox1.Text 
     End Get 
     Set(ByVal Value As String) 
      Me.TextBox1.Text = Value     ' Control is not updated of the SubForm. 
      Debug.Print("Value = " & Value)   ' The Value is Passed Correctly. 
      Debug.Print("Text = " & TextBox1.Text) ' And the property of the control has been updated. 
     End Set 
    End Property 
End Class 

非常感谢

千电子伏

回答

1

在你点击链接你引用的类名SubForm,这在VB.NET被称为一种形式的default automatic instance,但这是不一样的您在中显示的实例。在此创建一个名为objSubForm的不同实例,这是您显示的实例。

要解决,你需要保持objSubForm作为一个全球性的实例,是指这个全球性当你点击

Public Class MainForm 
    Dim objSubForm As SubForm 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     objSubForm.SetText = Me.TextBox1.Text ' Try to change contents of a TextBox on the SubForm 
     Me.TextBox2.Text = objSubForm.SetText ' Data comes back as expected, but the subform textbox remains unchanged. 
    End Sub 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     objSubForm = New SubForm() 
     objSubForm.TopLevel = False 
     Me.Panel1.Controls.Add(objSubForm) 
     objSubForm.Show() 
    End Sub 
End Class 

请记住,这改变后,你有责任有效地关闭和处置的全局实例。

Private Sub Form1_FormClosed(sender as Object, e as FormClosedEventArgs) _ 
    Handles Form1.FormClosed 
    if objSubForm IsNot Nothing 
     objSubForm.Close 
    End If 
    objSubForm = Nothing 
End Sub 
+1

谢谢,这工作得很好。我编辑了一下你的代码,以从Form_Load事件中移除DIM,因为我们现在已经在全局引用了该DIM。 – Kev 2014-12-07 10:08:46

+0

是的,通常的复制/粘贴错误。我说,如果我每次能够得到1欧元,我就会陷入这个困境中,现在我将成为百万富翁 – Steve 2014-12-07 10:10:46

0

谢谢史蒂夫,我根据您的修复在半小时内应用了新代码。

下面是我的代码的一个基本示例,它给了我可以更新的14个子表单。

我已经不再在子表单中创建属性,而是直接更新TextBox控件。

该解决方案给了我“更多”更少的代码,现在我可以添加另一个细节到一个子窗体并显示所有进程。

再次感谢! Kev

Public Class MainForm 
Dim objSubForm(14) As SubForm 
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    'Update the 14 forms 
    For n = 0 To 13 
     objSubForm(n).TextBox1.Text = Me.TextBox1.Text & " " & n 
    Next 
End Sub 
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    ' create 14 subforms 
    For n = 0 To 13 
     objSubForm(n) = New SubForm() 
     objSubForm(n).TopLevel = False 
     Me.Panel1.Controls.Add(objSubForm(n)) 
     objSubForm(n).Location = New Point(0, 20 * n) 
     objSubForm(n).Show() 
    Next 
End Sub 
Private Sub MainForm_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed 
    ' CLear up 
    If objSubForm IsNot Nothing Then 
     For n = 0 To 13 
      objSubForm(n).Close() 
     Next 
    End If 
    For n = 0 To 13 
     objSubForm(n) = Nothing 
    Next 
End Sub 
End Class 
+0

恩,我会离开这个地产。直接访问Form的内部控件似乎并不是遵循面向对象的范式的最明智的方式。将来,如果你需要改变这个文本框的内容,你的手就会被直接访问这个控件并且你的表单变得紧密结合在一起。 – Steve 2014-12-08 09:11:25