tags:

views:

4106

answers:

5

I have a simple contact book. The application has a main window that's an mdi form. When a contact is added using the "add a contact" form, I want to show a simple feedback message in the parent window status bar saying that the contact was added successfully.

Here's the child loading:

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

The problem is that since the parent is actually an mdi parent, and the "add a contact" form is launched with .Show() instead of .ShowDialog(), I can't store any return value that can be used by the launching Sub to perform an action.

Is there a way to pass a value from this child to the mdi parent? Here's the child form doing it's stuff:

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. Apparently, I'm rather bad at tagging things...so anyone wanting to retag this question are most welcome.

+4  A: 

The way I would handle this, is to create a custom event on the child control. Then handle the event on the parent control.

First, define the event in the child control (example, define your own):

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

Then, raise the event on the child control when your data is ready to be passed.

RaiseEvent EVENTNAME(Me, txtBoxWithReturnValue.Text)

Once you got that done, on the parent form now, you may handle the custom event. To do this, you need to add a listener, to "listen" for the event when it fires:

AddHandler CONTROLNAME.EVENTNAME, AddressOf EVENTNAME

Then, you may write a routine to handle this new event in your parent form:

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

'Code to handle data here

End Sub
Jon
Sorry, but where in the parent form do I put the Handler? What does CONTROLNAME refer to?
Mussnoon
You would put the handler right after you create the child form. This is similar to this post: http://stackoverflow.com/questions/1774386/how-to-declare-events-on-class-library-dll-and-catch-them-on-form/1775453#1775453
Walter
A: 

Create a controller class in the MDI and pass this as a parameter to the child form. When before the Me.Close() assign the contactlist to a property on the controller.

You need to seperate your data and your GUI more. For more info on the Model-View-Controller pattern go here.

Gerrie Schenck
A: 

Jon's answer - although quite helpful - is incomplete. And the missing part can cause confusion to newbies like myself.

Instead of dimming up the addForm like I did initially, one needs to create an instance of addForm at the class level using the WithEvents keyword, and then use this instance to both load the form and in the eventhandler.

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

But this leads to the "Cannot access a disposed object..." exception when trying to load the oneAddForm form after closing it once.

Mussnoon
A: 

Hey man, I see you posted this a while ago.. but I ran into the same issue. In VB.NET you can use the [My] namespaces. My.Forms.[name of your mdi form] so ... if your main form was called MdiMain you could do something like this.

My.Forms.MdiMain.lblStatus = "X"

All of my child forms inherit the same base class, and that class just has a property that returns the My.Forms.MdiMain . I called it MdiParentForm. That way I can just say Me.MdiParentForm on any form and bam... thats the parent.(less typing)

C# has an Application shindig that can be used, but we're not talking C#.

Hope this helped..

Cheers!

kroolk
A: 

Hi,

This is the simpless answer, no events!

Situation : 1 MdiParent form (Form1) and 2 child control forms (Control1Form and Control2Form). At startup the child controls are created (control1 and control2) in the MdiParent.

Form1 has as label in StatusStrip named StatusLabel. Control2 has a button named Button1

Objectives : When Control2's button is clicked, Control2 writes to the Title of control1 and to the StatusLabel of Form1

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

And voila! Hope it helps

Jean Amnotte