4

我有一个简单的通讯录。该应用程序有一个主窗口,它是一个 mdi 表单。当使用“添加联系人”表单添加联系人时,我想在父窗口状态栏中显示一条简单的反馈消息,说明联系人已成功添加。

这是子加载:

Private Sub addButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addButton.Click
    Dim af As New addForm
    af.MdiParent = Me
    af.Show()
End Sub

问题是,由于父级实际上是一个 mdi 父级,并且“添加联系人”表单是使用.Show()而不是启动的.ShowDialog(),所以我无法存储任何可以由启动 Sub 用于执行操作的返回值。

有没有办法将这个孩子的值传递给 mdi 父母?这是子窗体做它的东西:

Private Sub addButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addButton.Click

    Dim contact = <contact>
                      <quickName><%= quickNameTextBox.Text %></quickName>
                      <firstName><%= firstNameTextBox.Text %></firstName>
                      <lastName><%= lastNameTextBox.Text %></lastName>
                      <email><%= emailTextBox.Text %></email>
                      <website><%= websiteTextBox.Text %></website>
                      <telephone><%= telephoneTextBox.Text %></telephone>
                      <mobile><%= mobileTextBox.Text %></mobile>
                  </contact>

    Dim contactList = XDocument.Load("contactList.xml")

    contactList.Elements()(0).Add(contact)
    contactList.Save("contactList.xml")
    //something here to trigger the status update in the parent?
    //trivia: SO doesn't support VB single-quote comments...
    Me.Close()

End Sub

PS显然,我在标记事物方面相当糟糕......所以任何想要重新标记这个问题的人都非常受欢迎。

4

6 回答 6

6

我处理这个问题的方法是在子控件上创建一个自定义事件。然后处理父控件上的事件。

首先,在子控件中定义事件(例如,定义自己的):

Public Event EVENTNAME(ByVal sender as Object, ByVal ValueToReturn As String)

然后,当您的数据准备好传递时,在子控件上引发事件。

RaiseEvent EVENTNAME(Me, txtBoxWithReturnValue.Text)

完成后,现在在父表单上,您可以处理自定义事件。为此,您需要添加一个侦听器,以便在事件触发时“侦听”事件:

AddHandler CONTROLNAME.EVENTNAME, AddressOf EVENTNAME

然后,您可以编写一个例程来处理父表单中的这个新事件:

Private Sub FUNCTIONAME(ByVal sender As System.Object, ByVal ValueToReturn as String) Handles CONTROLNAME.EVENTNAME

'Code to handle data here

End Sub
于 2009-02-19T14:20:56.920 回答
1

这是最简单的答案,没有事件!

情况:1 个 MdiParent 表单(Form1)和 2 个子控件表单(Control1Form 和 Control2Form)。启动时,在 MdiParent 中创建子控件(control1 和 control2)。

Form1 在 StatusStrip 中具有名为 StatusLabel 的标签。Control2 有一个名为 Button1 的按钮

目标:当 Control2 的按钮被点击时,Control2 写入 control1 的 Title 和 Form1 的 StatusLabel

PARTIAL CODE

FORM1
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
control1 = New Control1Form
control2 = New Control2Form
control1.MdiParent = Me
control1.Show()
control2.MdiParent = Me
control2.Show()
End Sub
End Class


CONTROL2FORM
Public Class Control2Form
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
'Title of Control1
CType(Me.ParentForm, Form1).control1.Text = "Title bar text"
'Status Strip Label
CType(Me.ParentForm, Form1).StatusLabel.Text = "Status Strip Text"
End Sub
End Class

瞧!希望能帮助到你

于 2010-07-29T18:20:46.247 回答
1

在 VB.NET 中,您可以使用 [My] 命名空间。My.Forms.[你的 MDI 表单的名称] 所以......如果你的主表单被称为 MdiMain 你可以做这样的事情。

My.Forms.MdiMain.lblStatus = "X"

我所有的子表单都继承同一个基类,并且该类只有一个返回 My.Forms.MdiMain 的属性。我称它为 MdiParentForm。这样我就可以在任何形式上说 Me.MdiParentForm 和 bam ......那就是父母。(少打字)

于 2009-07-09T20:38:26.370 回答
0

在 MDI 中创建一个控制器类并将其作为参数传递给子窗体。在 Me.Close() 之前将联系人列表分配给控制器上的属性。

您需要更多地分离数据和 GUI。有关模型-视图-控制器模式的更多信息,请访问此处

于 2009-02-19T14:22:59.177 回答
0

乔恩的回答 - 虽然很有帮助 - 是不完整的。缺少的部分可能会让像我这样的新手感到困惑。

不是像我一开始那样调暗 addForm,而是需要使用 WithEvents 关键字在类级别创建 addForm 的实例,然后使用该实例来加载表单和事件处理程序。

Private WithEvents oneAddForm As New addForm //create a new instance of addForm

Private Sub addButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addButton.Click
    oneAddForm.MdiParent = Me
    oneAddForm.Show()
End Sub
//using this instance to load the form...

Private Sub updateStatus(ByVal sender As System.Object, ByVal contactName As String) Handles oneAddForm.addSuccess
    statusLabel.Text = contactName & " has been added to your contact list."
End Sub
//...and to put in the event handler

但这会导致“无法访问已处置的对象...”在关闭一次后尝试加载 oneAddForm 表单时出现异常。

于 2009-02-19T16:38:35.493 回答
-1

我想添加一个对我来说非常有用的稍微不同的答案。

只要我确实在 MDI 父级中进行了任何代码更改,上述答案中的以下内容对我来说非常有用。当我插入相当于 form1.MDIparent=me 时,一切都失败了。所以我离开了这一步。

下面的 Form1 需要是您正在使用的 MDI 父窗体的名称。然后它在我的环境中工作,非常适合将变量传递给父级或追求父级的其他功能。

在这样做之前,我遇到了一个问题,孩子打电话给另一个有所有空白字段的父母!

CType(Me.ParentForm, Form1).control1.Text = "Title bar text"
'Status Strip Label
CType(Me.ParentForm, Form1).StatusLabel.Text = "Status Strip Text"

CType(Me.parentForm, Form1).variableDefinedinParentString = "abc" 'passing a variable

CType(Me.parentForm, Form1).subroutineLOCATEDinPARENT() 'Calling a subroutine in the parent

也许这会帮助其他一些人。但愿如此!

于 2015-05-08T22:16:20.840 回答