在VB.net中将值从child传递给mdi parent

时间:2009-02-19 14:00:35

标签: .net vb.net mdi

我有一本简单的联系簿。该应用程序有一个主窗口,它是一个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

P.S。显然,我很擅长标记事物......所以任何想要重新提出这个问题的人都是最受欢迎的。

6 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

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

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

目标:当单击Control2的按钮时,Control2会写入control1的标题和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

瞧! 希望它有所帮助

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

Jon的回答 - 尽管很有帮助 - 但是不完整。缺少的部分可能会让像我这样的新手感到困惑。

不像我最初那样调整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表单之后尝试加载oneAddForm表单时,这会导致“无法访问已处置对象...”异常。

答案 4 :(得分:0)

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

My.Forms.MdiMain.lblStatus = "X"

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

答案 5 :(得分:-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

也许这会对其他人有所帮助。我希望如此!