VB.NET从Form2修改Form1中的标签

时间:2019-12-14 00:57:48

标签: vb.net forms

我知道有上百万个主题,但是我发现的每个解决方案都不能满足我的需要(仅从Form1到Form2可用),或者是关于C#而不是VB.NET

为简单起见,假设我有一个带有标签(LBLtest)和一个按钮(BUTtest)的Form1。 然后,我有一个带有两个按钮(BUToption1)和(BUToption2)的Form2。如果单击BUToption1,我希望Form2隐藏并且LBLtest读取“您已选择选项1”。如果我单击BUToption2,我希望Form2隐藏并且LBLtest读为“您已选择了选项2”。

在Visual Studio 2012中,我曾经用Form1编写过:

Private Sub BUTtest_Click(sender As Object, e As EventArgs) Handles BUTtest.Click
Form2.show()
End Sub

然后在Form2中:

Private Sub BUToption1_Click(sender As Object, e As EventArgs) Handles BUToption1.Click
Form1.LBLtest.text = "You've chosen option 1"
Me.Hide()
End Sub

一切都会像在梦中一样运作。 现在在Visual Studio 2019中这根本不起作用,因为它不允许我在不声明表单本身的对象的情况下从另一个表单调用任何东西。

现在我用Form1编写:

Private Sub BUTtest_Click(sender As Object, e As EventArgs) Handles BUTtest.Click
Dim SecondForm as New Form2()
SecondForm.show()
End Sub

在Form2中,我不知道该写些什么,因为如果我使用相同的“ Dim FirstForm和New Form1()”,程序将执行的操作是创建一个新对象Form1,而不是一个新对象。已经打开,打开的Form1中看不到任何更改。

(我也不知道为什么它在2012年曾经如此简单,现在是如此痛苦)。

任何帮助将不胜感激。

注意:Form2隐藏而不是关闭很重要。在另一种情况下,将有单选按钮和其他内容,当表单再次显示时,我希望所选的选项仍然存在,以便进行修改。如果关闭,它将从头开始打开。

1 个答案:

答案 0 :(得分:1)

您将以完全错误的方式进行此操作。正确的方法是让Form1创建一个Form2实例,将它需要的任何数据传递给它,然后通过调用ShowDialog来显示它。当用户单击Button上的Form2时,它将关闭并返回ShowDialog调用。 Form1然后根据需要使用Form2的返回值和/或适当的属性值。如果您需要再次显示Form2,请创建一个新实例,然后将其需要的所有数据再次传递给它。您无需隐藏Form2即可维持状态。您可以将表示其状态的数据存储在适当的位置,然后在下次显示时使用该数据。

这是一个例子。我刚刚创建了一个具有两种形式的项目。在Form2上,我添加了两个Buttons和一个ComboBox。这是Form2的代码:

'The SelectedIndex of the ComboBox.
Public Property SelectedIndex As Integer

'The text for the Button that was clicked.
Public Property OptionText As String

Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    'Select the same item that was selected last time.
    ComboBox1.SelectedIndex = SelectedIndex
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'Remember what item was selected.
    SelectedIndex = ComboBox1.SelectedIndex

    'Indicate what Button was clicked.
    OptionText = "Option 1"

    'Close this instance permanently.
    Close()
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    'Remember what item was selected.
    SelectedIndex = ComboBox1.SelectedIndex

    'Indicate what Button was clicked.
    OptionText = "Option 2"

    'Close this instance permanently.
    Close()
End Sub

Form1上,我添加了ButtonLabel。这是Form1的代码:

'The SelectedIndex of the ComboBox on Form2.
Private form2SelectedIndex As Integer = -1

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'Create a new instance of Form2.
    Using dialogue As New Form2
        'Tell the dialogue what item to select.
        dialogue.SelectedIndex = form2SelectedIndex

        'Show the dialogue modally.
        dialogue.ShowDialog()

        'Remember what item was selected.
        form2SelectedIndex = dialogue.SelectedIndex

        'Display the text based on which Button was clicked.
        Label1.Text = dialogue.OptionText
    End Using
End Sub

如果创建并运行这样的项目,您将看到它完全按预期运行。每次在Label上单击Form1并进入Button的状态时,正确的文本都会显示在{{1}上的Form2中,在这种情况下, Form2中的“-”保持不变,无论您打开和关闭对话框多少次。

请注意,ComboBox完全不知道Form2的存在,这正是应该的样子。您应尽可能避免这种紧密耦合。就目前而言,您可以在完全不同的场景中使用相同的Form1类,并且它仍然可以工作,因为它对Form2或其包含的控件没有特定的依赖性。任一种对窗体上控件进行的更改都只能通过该窗体完成。甚至在Form1上,Form2只是通过属性提供数据,Form1的工作取决于如何根据数据修改自己的控件。

要显示VS 2019支持默认实例的方式与自2005年以来的每个版本完全相同,您可以更改Form2中的代码,如下所示:

Form1

运行该命令,从用户的角度来看,它的工作方式完全相同。实际上,当您通过调用'The SelectedIndex of the ComboBox on Form2. Private form2SelectedIndex As Integer = -1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Use the default instance of Form2. 'Tell the dialogue what item to select. Form2.SelectedIndex = form2SelectedIndex 'Show the dialogue modally. Form2.ShowDialog() 'Remember what item was selected. form2SelectedIndex = Form2.SelectedIndex 'Display the text based on which Button was clicked. Label1.Text = Form2.OptionText End Sub 显示表单时,关闭它不会丢弃它。在第一种情况下,ShowDialog实例是通过Form2语句创建的,因此它将被放置在Using语句中,这意味着每次都必须创建一个新实例。如果不处理它,则实际上可以再次显示相同的实例。这意味着您可以使用默认实例,而不必记住状态,因为它每次都是相同的实例。这意味着您可以将代码简化为:

End Using

这:

'The text for the Button that was clicked.
Public Property OptionText As String

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'Indicate what Button was clicked.
    OptionText = "Option 1"

    'Close this instance permanently.
    Close()
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    'Indicate what Button was clicked.
    OptionText = "Option 2"

    'Close this instance permanently.
    Close()
End Sub

,它将按预期工作。也就是说,大多数有经验的开发人员都避免使用默认实例,建议其他人也避免使用默认实例。它们的存在主要有两个原因:帮助不了解对象如何工作的初学者以及帮助VB6开发人员迁移习惯于以这种方式工作的表单。如果您想成为VB.NET开发人员,则最好像对待其他对象一样对待表单,即根据需要创建和销毁实例。

有关表单之间交流的更多信息,您可以阅读我的博客文章here,该文章分为三部分。第一部分是关于默认表单实例的。值得一读,但正如我所说,我建议不要使用它们。第二部分是做事的骇人方式,第三部分是做事的“适当”方式。