Passing an object back to a form

  • Thread starter Thread starter BobRoyAce
  • Start date Start date
B

BobRoyAce

I am developing an application in VS2005, using VB.NET.

Suppose that I have a class, called Widget, which contains, among
other things, a List(Of WidgetDetail), where WidgetDetail is another
class.

Now, let's say that I have a Widget form, called WidgetForm, and that
it is used to enter Widgets. This form currently has a private module-
level variable, called m_oCurrentWidget which is an instance of
Widget. On WidgetForm, there is a button to add a new WidgetDetail to
be associated with the Widget being worked on currently on
WidgetForm.

When the user clicks on this button, another form, called
WidgetDetailForm, is shown that is used to enter information for a
WidgetDetail. The WidgetDetailForm form currently has a private module-
level variable, called m_oCurrentWidgetDetail, which is an instance of
WidgetDetail.

Well, what I want to do when the user clicks on the button, on the
WidgetDetailForm form, to confirm addition of the WidgetDetail, is to
add the WidgetDetail object defined on WidgetDetailForm, to
m_oCurrentWidget's WidgetDetailList (e.g.
m_oCurrentWidget.WidgetDetailList.Add(m_oCurrentWidgetDetail)). Given
that m_oCurrentWidget and m_oCurrentWidgetDetail are on two different
forms, what is the best way to implement something like this?

The more general question is, what's the best way to pass back an
Object from a form on which it is created?
 
BobRoyAce said:
The more general question is, what's the best way to pass back an
Object from a form on which it is created?

You could do something like add a readonly property to the child form of
type WidgetDetail called something like SelectedWidget, and then after
calling ChildForm.Show() just pull out the object from the property:

Dim ChildForm as New WidgetForm()
ChildForm.Show(true)
m_oCurrentWidget.Add(ChildForm.SelectedWidget)
 
Thanks Leon...

I was thinking something like that. However, what confuses me is that
I am attempting to reference the readonly property of ChildForm AFTER
it has been shown (i.e. AFTER it has CLOSED). How is it that I'm able
to reference that property after the ChildForm is closed? Is it still
in memory? If yes, when does it go away?
 
I should have mentioned that I will be be doing ChildForm.ShowDialog
rather than ChildForm.Show.
 
BobRoyAce said:
I should have mentioned that I will be be doing ChildForm.ShowDialog
rather than ChildForm.Show.

Remember that when showing a form you are just calling a method on a class
you have instantiated, consider the code I posted before (edited to use
ShowDialog):

Dim ChildForm as New WidgetForm()
ChildForm.ShowDialog()
m_oCurrentWidget.Add(ChildForm.SelectedWidget)

The ChildForm object has not gone out of scope or otherwise been destroyed,
its visibility has nothing to do with its existence (except as far as the
user is concerned).
 
The ChildForm object has not gone out of scope or otherwise been destroyed,
its visibility has nothing to do with its existence (except as far as the
user is concerned).

Good point. For some reason I thought that when a form "closed", it
"went away". That was silly of me. So, if I wanted to be all neat and
tidy about things, I could add a line

ChildForm = Nothing

to facilitate freeing the memory (without just waiting for garbage
collection to do it), I suppose. I would, of course, do this after
pulling any information I need from ChildForm.

Thanks...
 
Good point. For some reason I thought that when a form "closed", it
"went away". That was silly of me. So, if I wanted to be all neat and
tidy about things, I could add a line

ChildForm = Nothing

to facilitate freeing the memory (without just waiting for garbage
collection to do it), I suppose. I would, of course, do this after
pulling any information I need from ChildForm.

Thanks...

Setting the reference to Nothing does not cause the object to be
disposed. Only calling the object's Dispose method does that.

If the ChildForm variable has scope beyond the current method, then
setting it to Nothing will make the object available for garbage
collection sooner.
 
I disagree with this approach. A cleaner approach would be to add a public
property to the parent form, and set it in the child form (to which you
would pass a reference to the parent form). It's best not to check
properties in the child form after you've closed it.

An even cleaner approach would be to have the parent call a method in the
child form that returns what you want, and have the child form show itself
and return the list, like this:

In the child:

Private newWidget as oWidget = Nothing

Public Function GetWidget() As oWidget

Me.ShowDialog()

If (Me.DialogResult = Windows.Forms.DialogResult.OK) Then _
Return newWidget
Else
Return Nothing
End If

End Function

Private Function SaveStuff()
'validate? this would run when the user hits OK
Me.DialogResult = Windows.Forms.DialogResult.OK
End Function

In the parent:

Dim getWidget as oWidget

getWidget = (New childForm).GetWidget 'this will show the childForm

If (getWidget Is Nothing)
'they cancelled
Else
'add it to your list
End IF


RobinS.
---------------------------------
 
RobinS said:
An even cleaner approach would be to have the parent call a method in the
child form that returns what you want, and have the child form show itself
and return the list, like this:

In the child:

Private newWidget as oWidget = Nothing

Public Function GetWidget() As oWidget

Me.ShowDialog()

If (Me.DialogResult = Windows.Forms.DialogResult.OK) Then _
Return newWidget
Else
Return Nothing
End If

End Function

Private Function SaveStuff()
'validate? this would run when the user hits OK
Me.DialogResult = Windows.Forms.DialogResult.OK
End Function

In the parent:

Dim getWidget as oWidget

getWidget = (New childForm).GetWidget 'this will show the childForm

If (getWidget Is Nothing)
'they cancelled
Else
'add it to your list
End IF

That's not really much different than the solution I posted, apart from (as
you stated correctly) checking the form status which I left out, as you
would have to set this in your OK and Cancel button's event handlers on the
child form.
 
I disagree with this approach. A cleaner approach would be to add a public
property to the parent form, and set it in the child form (to which you
would pass a reference to the parent form). It's best not to check
properties in the child form after you've closed it.

An even cleaner approach would be to have the parent call a method in the
child form that returns what you want, and have the child form show itself
and return the list, like this:

In the child:

    Private newWidget as oWidget = Nothing

    Public Function GetWidget() As oWidget

        Me.ShowDialog()

        If (Me.DialogResult = Windows.Forms.DialogResult.OK) Then _
            Return newWidget
        Else
            Return Nothing
        End If

    End Function

    Private Function SaveStuff()
        'validate? this would run when the user hits OK
        Me.DialogResult = Windows.Forms.DialogResult.OK
    End Function

In the parent:

    Dim getWidget as oWidget

    getWidget = (New childForm).GetWidget   'this will show the childForm

    If (getWidget Is Nothing)
        'they cancelled
    Else
        'add it to your list
    End IF

RobinS.







- Show quoted text -

I agree and any other object could call it as well without hardcoding
the child to work with one form. Plus making a reference call to a
memory released object just is bad in theory and makes the your code
read harder.
 
AlexW said:
Plus making a reference call to a
memory released object just is bad in theory and makes the your code
read harder.

The class will not have been released from memory after .ShowDialog() has
been called.
 
Back
Top