PC Review


Reply
Thread Tools Rate Thread

Calling a method in one MDI child from another MDI child

 
 
Earl
Guest
Posts: n/a
 
      20th Dec 2006
I need to call a method on an owned child form, and am wondering if the best
way of doing this is to capture the Closing event of the form that passes
control back to the form where I have the method. The structure is like so:

frmMain (MDI, runs on app start) calls
frmB (MDI child), which in turn calls
frmC (MDI child), which in turn calls
frmD (MDI child).

frmMain and frmB remain open while frmC and frmD are shown.

frmC and frmD each close as they finish processing.

Once the user makes selections, frmD then needs to pass control back to frmB
(right before closing) and fire a method that populates certain controls on
frmB. So my first thought is to add a handler to frmB to capture the Closing
event of frmD, and use that handler to call the method to populate the
controls on frmB. Is there a better way, either easier, more
straightforward, or more efficient?


 
Reply With Quote
 
 
 
 
Robson Siqueira
Guest
Posts: n/a
 
      20th Dec 2006
Earl,

Why don't you use delegates? Pass a delegate object at the time you
instantiate the second child form.

Rgs,

Robson Siqueira

"Earl" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>I need to call a method on an owned child form, and am wondering if the
>best way of doing this is to capture the Closing event of the form that
>passes control back to the form where I have the method. The structure is
>like so:
>
> frmMain (MDI, runs on app start) calls
> frmB (MDI child), which in turn calls
> frmC (MDI child), which in turn calls
> frmD (MDI child).
>
> frmMain and frmB remain open while frmC and frmD are shown.
>
> frmC and frmD each close as they finish processing.
>
> Once the user makes selections, frmD then needs to pass control back to
> frmB (right before closing) and fire a method that populates certain
> controls on frmB. So my first thought is to add a handler to frmB to
> capture the Closing event of frmD, and use that handler to call the method
> to populate the controls on frmB. Is there a better way, either easier,
> more straightforward, or more efficient?
>



 
Reply With Quote
 
Raaj
Guest
Posts: n/a
 
      20th Dec 2006
Earl,

In my opinion rather than FormD notifying FormB of happening of an
event, FormB should be retrieving this information from FormD (or
through FormC per your example). That would make FormD independent and
agnostic about notifying other objects (FormB in this case). To
complicate things in MDI you can have multiple instances of FormB's,
FormC's and FormD's at any given point.
What we need to figure out is a way to pass information between these
forms. Considering these, I would set the behavior of FormD (and FormC
*may be* per your example) to modal instead of mdichild. That way FormB
has reference to FormC->/FormD through which it would retrieve the
necessary information the code would look something like this:

FormD newMdiChild = new FormD();
if (newMdiChild.ShowDialog(this) == DialogResult.OK)
{
this.SomeValue = newMdiChild.SomeProperty;
//retreive other values ..so on
}


Raaj.

Earl wrote:
> I need to call a method on an owned child form, and am wondering if the best
> way of doing this is to capture the Closing event of the form that passes
> control back to the form where I have the method. The structure is like so:
>
> frmMain (MDI, runs on app start) calls
> frmB (MDI child), which in turn calls
> frmC (MDI child), which in turn calls
> frmD (MDI child).
>
> frmMain and frmB remain open while frmC and frmD are shown.
>
> frmC and frmD each close as they finish processing.
>
> Once the user makes selections, frmD then needs to pass control back to frmB
> (right before closing) and fire a method that populates certain controls on
> frmB. So my first thought is to add a handler to frmB to capture the Closing
> event of frmD, and use that handler to call the method to populate the
> controls on frmB. Is there a better way, either easier, more
> straightforward, or more efficient?


 
Reply With Quote
 
Earl
Guest
Posts: n/a
 
      21st Dec 2006
Good food for thought Raaj.

I could almost move the controls and logic of FormB back to the main form --
if I did not want to keep it as an independent entity. The point being, I
only need one copy of it ever in the app. And the design of the main form is
so clean, it merely controls the app, does the intial checks, hosts the
menustrip, etc.

FormC on the other hand could indeed be called multiple times. But it too is
only needed once for every iteration of FormB (FormC gets spawned by a
button click on FormB only). And the flow of data and control is one-way: if
a certain search condition is met, either FormD gets shown or we fall back
into FormB.

FormD can only get created by FormC. Seems a remote possibility, but not
impossible that it could be created more than once (altho I can prevent
that).

I'm not sure how you are envisioning FormB retrieving information from
FormD. May be a matter of semantics, I view it as FormD passing the
information back to FormB.




"Raaj" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Earl,
>
> In my opinion rather than FormD notifying FormB of happening of an
> event, FormB should be retrieving this information from FormD (or
> through FormC per your example). That would make FormD independent and
> agnostic about notifying other objects (FormB in this case). To
> complicate things in MDI you can have multiple instances of FormB's,
> FormC's and FormD's at any given point.
> What we need to figure out is a way to pass information between these
> forms. Considering these, I would set the behavior of FormD (and FormC
> *may be* per your example) to modal instead of mdichild. That way FormB
> has reference to FormC->/FormD through which it would retrieve the
> necessary information the code would look something like this:
>
> FormD newMdiChild = new FormD();
> if (newMdiChild.ShowDialog(this) == DialogResult.OK)
> {
> this.SomeValue = newMdiChild.SomeProperty;
> //retreive other values ..so on
> }
>
>
> Raaj.
>
> Earl wrote:
>> I need to call a method on an owned child form, and am wondering if the
>> best
>> way of doing this is to capture the Closing event of the form that passes
>> control back to the form where I have the method. The structure is like
>> so:
>>
>> frmMain (MDI, runs on app start) calls
>> frmB (MDI child), which in turn calls
>> frmC (MDI child), which in turn calls
>> frmD (MDI child).
>>
>> frmMain and frmB remain open while frmC and frmD are shown.
>>
>> frmC and frmD each close as they finish processing.
>>
>> Once the user makes selections, frmD then needs to pass control back to
>> frmB
>> (right before closing) and fire a method that populates certain controls
>> on
>> frmB. So my first thought is to add a handler to frmB to capture the
>> Closing
>> event of frmD, and use that handler to call the method to populate the
>> controls on frmB. Is there a better way, either easier, more
>> straightforward, or more efficient?

>



 
Reply With Quote
 
Raaj
Guest
Posts: n/a
 
      21st Dec 2006
> Good food for thought Raaj.
>
> I could almost move the controls and logic of FormB back to the main form --
> if I did not want to keep it as an independent entity. The point being, I
> only need one copy of it ever in the app. And the design of the main form is
> so clean, it merely controls the app, does the intial checks, hosts the
> menustrip, etc.

No not really you don't have to change anything in MainForm or FormB,
they are good. There is nothing wrong with FormB in my perspective
either. I was referring to FormD which will be dependent if it
references anything in FormB (Refer to my example below for what I
mean)

> FormC on the other hand could indeed be called multiple times. But it too is
> only needed once for every iteration of FormB (FormC gets spawned by a
> button click on FormB only). And the flow of data and control is one-way: if
> a certain search condition is met, either FormD gets shown or we fall back
> into FormB.


I agree

> FormD can only get created by FormC. Seems a remote possibility, but not
> impossible that it could be created more than once (altho I can prevent
> that).

It appears we both are on the same page here


> I view it as FormD passing the information back to FormB.

I somewhat disagree

> I'm not sure how you are envisioning FormB retrieving information from
> FormD.

The following should explain what I visualize when I say FormB should
retrieve information from FormD

To simplify, let's consider a realistic example and for sake of
example assume the hierarchy is as follows. Please note that the code
below is not compiled and it is for illustration only (typewritten in
notepad)

UI Hierarchy
=========
MainForm

|
FormOrder (MdiChild)(FormB per our example) (Populates
IPoOrder)
|

FormOrderItems (Modal Form) (FormC per our
example) (Populates IPoItemCol)
|

FormOrderLineItem (Modal Form) (FormD per
our example) (Populates IPoItem)


In the below code FormOrder creates an instance of the FormOrderItems
and ultimately gets an instance of order collection. In addition,
FormOrder of course will have reference to other controls may be to
Order Header related information (IPoOrder)

//Code Snippet in FormOrder
private void buttonEnterLineItems_Click(object sender, EventArgs e)
{
EnterOrderLines();
}

private void EnterOrderLines()
{
FormOrderItems objFormOrderItems = new FormOrderItems();
if (objFormOrderItems.ShowDialog(this) == DialogResult.OK)
{
//if all is *well* objFormOrderItems would retrieve an instance
of IPoItemCol
this.PoOrder.PoItemCol = objFormOrderItems.GetOrderCollections;
if ((this.PoOrder.PoItemCol == null) ||
(this.PoOrder.PoItemCol.Count <= 0))
throw new EOrderException(....) //exception to business
rules...
}
}


The FormOrderItems creates (or reuses) an instance of FormOrderLineItem
for every new item in the order. FormOrderItems is responsible for
populating the Orderlines Collection instance with instances of
orderline.

//Code in FormOrderItems
private void buttonNewItem_Click(object sender, EventArgs e)
{
AddLineItem();
}


private void AddLineItem()
{
FormOrderLineItem objFormOrderLineItem = new FormOrderLineItem();
if objFormOrderLineItem.ShowDialog(this) == DialogResult.OK)
{
//if all is well objFormOrderLineItem would return a valid IPoItem
IPoItem PoItem = objFormOrderLineItem.GetLineItem;
If (PoItem == null)
throw new EOrderLineException(...); //Exception
this.PoItemCol.Add(POItem);

}

}

Apparently notice that OrderLines collection is passed to the
FormOrders. This is what I originally meant when I said the FormB
should retrieve details from FormD.

Also, When I say FormB should retrieve details that also correlates to
this statement "Given its position (and logical functionality) in the
hierarchy FormD should have no idea who its users are and what there
business are. On the other end all that users (FormB or FormC) of FormD
know in a nut shell is given a set of inputs FormD throws a set of
predefined output or exception to business rules"

This is how I view it:

1. FormOrderLine (FormD) Item should not know anything about
FormOrderLines (FormC) or FormOrder (FormB)

2. If FormOrderLine has reference to any of the attributes or events in
the FormOrderLines or FormOrder they are interwoven. Then this isn't
reusable either, think of a generic lookup collection such as customer
lookup. If the Customerlookup subscribes to events or methods specific
to order form (Orders Module) then it is an initiation to coupling. The
customerLookup now is no more a blackbox component, nor can we reuse it
in other modules as efficiently. Given its functionality, let us say we
have to (or forced to) resuse the CustomerLookup in an Invoice Form
(Invoicing Module) we will be tempted to subscribe to events or
delegates in Invoice form aswell in the advert of *reusability*. The
Customerlookup would end up as an interconnected mass of spaghetti over
a couple of iterations.

I hope I have articulated my thoughts in line to your question.

Raaj.

Earl wrote:
> Good food for thought Raaj.
>
> I could almost move the controls and logic of FormB back to the main form --
> if I did not want to keep it as an independent entity. The point being, I
> only need one copy of it ever in the app. And the design of the main form is
> so clean, it merely controls the app, does the intial checks, hosts the
> menustrip, etc.
>
> FormC on the other hand could indeed be called multiple times. But it too is
> only needed once for every iteration of FormB (FormC gets spawned by a
> button click on FormB only). And the flow of data and control is one-way: if
> a certain search condition is met, either FormD gets shown or we fall back
> into FormB.
>
> FormD can only get created by FormC. Seems a remote possibility, but not
> impossible that it could be created more than once (altho I can prevent
> that).
>
> I'm not sure how you are envisioning FormB retrieving information from
> FormD. May be a matter of semantics, I view it as FormD passing the
> information back to FormB.
>
>
>
>
> "Raaj" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > Earl,
> >
> > In my opinion rather than FormD notifying FormB of happening of an
> > event, FormB should be retrieving this information from FormD (or
> > through FormC per your example). That would make FormD independent and
> > agnostic about notifying other objects (FormB in this case). To
> > complicate things in MDI you can have multiple instances of FormB's,
> > FormC's and FormD's at any given point.
> > What we need to figure out is a way to pass information between these
> > forms. Considering these, I would set the behavior of FormD (and FormC
> > *may be* per your example) to modal instead of mdichild. That way FormB
> > has reference to FormC->/FormD through which it would retrieve the
> > necessary information the code would look something like this:
> >
> > FormD newMdiChild = new FormD();
> > if (newMdiChild.ShowDialog(this) == DialogResult.OK)
> > {
> > this.SomeValue = newMdiChild.SomeProperty;
> > //retreive other values ..so on
> > }
> >
> >
> > Raaj.
> >
> > Earl wrote:
> >> I need to call a method on an owned child form, and am wondering if the
> >> best
> >> way of doing this is to capture the Closing event of the form that passes
> >> control back to the form where I have the method. The structure is like
> >> so:
> >>
> >> frmMain (MDI, runs on app start) calls
> >> frmB (MDI child), which in turn calls
> >> frmC (MDI child), which in turn calls
> >> frmD (MDI child).
> >>
> >> frmMain and frmB remain open while frmC and frmD are shown.
> >>
> >> frmC and frmD each close as they finish processing.
> >>
> >> Once the user makes selections, frmD then needs to pass control back to
> >> frmB
> >> (right before closing) and fire a method that populates certain controls
> >> on
> >> frmB. So my first thought is to add a handler to frmB to capture the
> >> Closing
> >> event of frmD, and use that handler to call the method to populate the
> >> controls on frmB. Is there a better way, either easier, more
> >> straightforward, or more efficient?

> >


 
Reply With Quote
 
Earl
Guest
Posts: n/a
 
      21st Dec 2006
Thanks for the explanation Raaj. The form names being a little hard to
follow, I did grasp the hierarchy, and most importantly that you recommend
using modal forms for all sub-forms below the order form (or frmB in my
example). I also saw the use of the collections, although I am probably
going to organize the hierarchy slightly different in that I'm going to
simply expose properties on frmD to use on frmB. Once control is returned to
frmB, I'll call a method to uses the properties on frmD before Disposing of
frmC and frmD.

"Raaj" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>> Good food for thought Raaj.
>>
>> I could almost move the controls and logic of FormB back to the main
>> form --
>> if I did not want to keep it as an independent entity. The point being, I
>> only need one copy of it ever in the app. And the design of the main form
>> is
>> so clean, it merely controls the app, does the intial checks, hosts the
>> menustrip, etc.

> No not really you don't have to change anything in MainForm or FormB,
> they are good. There is nothing wrong with FormB in my perspective
> either. I was referring to FormD which will be dependent if it
> references anything in FormB (Refer to my example below for what I
> mean)
>
>> FormC on the other hand could indeed be called multiple times. But it too
>> is
>> only needed once for every iteration of FormB (FormC gets spawned by a
>> button click on FormB only). And the flow of data and control is one-way:
>> if
>> a certain search condition is met, either FormD gets shown or we fall
>> back
>> into FormB.

>
> I agree
>
>> FormD can only get created by FormC. Seems a remote possibility, but not
>> impossible that it could be created more than once (altho I can prevent
>> that).

> It appears we both are on the same page here
>
>
>> I view it as FormD passing the information back to FormB.

> I somewhat disagree
>
>> I'm not sure how you are envisioning FormB retrieving information from
>> FormD.

> The following should explain what I visualize when I say FormB should
> retrieve information from FormD
>
> To simplify, let's consider a realistic example and for sake of
> example assume the hierarchy is as follows. Please note that the code
> below is not compiled and it is for illustration only (typewritten in
> notepad)
>
> UI Hierarchy
> =========
> MainForm
>
> |
> FormOrder (MdiChild)(FormB per our example) (Populates
> IPoOrder)
> |
>
> FormOrderItems (Modal Form) (FormC per our
> example) (Populates IPoItemCol)
> |
>
> FormOrderLineItem (Modal Form) (FormD per
> our example) (Populates IPoItem)
>
>
> In the below code FormOrder creates an instance of the FormOrderItems
> and ultimately gets an instance of order collection. In addition,
> FormOrder of course will have reference to other controls may be to
> Order Header related information (IPoOrder)
>
> //Code Snippet in FormOrder
> private void buttonEnterLineItems_Click(object sender, EventArgs e)
> {
> EnterOrderLines();
> }
>
> private void EnterOrderLines()
> {
> FormOrderItems objFormOrderItems = new FormOrderItems();
> if (objFormOrderItems.ShowDialog(this) == DialogResult.OK)
> {
> //if all is *well* objFormOrderItems would retrieve an instance
> of IPoItemCol
> this.PoOrder.PoItemCol = objFormOrderItems.GetOrderCollections;
> if ((this.PoOrder.PoItemCol == null) ||
> (this.PoOrder.PoItemCol.Count <= 0))
> throw new EOrderException(....) //exception to business
> rules...
> }
> }
>
>
> The FormOrderItems creates (or reuses) an instance of FormOrderLineItem
> for every new item in the order. FormOrderItems is responsible for
> populating the Orderlines Collection instance with instances of
> orderline.
>
> //Code in FormOrderItems
> private void buttonNewItem_Click(object sender, EventArgs e)
> {
> AddLineItem();
> }
>
>
> private void AddLineItem()
> {
> FormOrderLineItem objFormOrderLineItem = new FormOrderLineItem();
> if objFormOrderLineItem.ShowDialog(this) == DialogResult.OK)
> {
> //if all is well objFormOrderLineItem would return a valid IPoItem
> IPoItem PoItem = objFormOrderLineItem.GetLineItem;
> If (PoItem == null)
> throw new EOrderLineException(...); //Exception
> this.PoItemCol.Add(POItem);
>
> }
>
> }
>
> Apparently notice that OrderLines collection is passed to the
> FormOrders. This is what I originally meant when I said the FormB
> should retrieve details from FormD.
>
> Also, When I say FormB should retrieve details that also correlates to
> this statement "Given its position (and logical functionality) in the
> hierarchy FormD should have no idea who its users are and what there
> business are. On the other end all that users (FormB or FormC) of FormD
> know in a nut shell is given a set of inputs FormD throws a set of
> predefined output or exception to business rules"
>
> This is how I view it:
>
> 1. FormOrderLine (FormD) Item should not know anything about
> FormOrderLines (FormC) or FormOrder (FormB)
>
> 2. If FormOrderLine has reference to any of the attributes or events in
> the FormOrderLines or FormOrder they are interwoven. Then this isn't
> reusable either, think of a generic lookup collection such as customer
> lookup. If the Customerlookup subscribes to events or methods specific
> to order form (Orders Module) then it is an initiation to coupling. The
> customerLookup now is no more a blackbox component, nor can we reuse it
> in other modules as efficiently. Given its functionality, let us say we
> have to (or forced to) resuse the CustomerLookup in an Invoice Form
> (Invoicing Module) we will be tempted to subscribe to events or
> delegates in Invoice form aswell in the advert of *reusability*. The
> Customerlookup would end up as an interconnected mass of spaghetti over
> a couple of iterations.
>
> I hope I have articulated my thoughts in line to your question.
>
> Raaj.
>
> Earl wrote:
>> Good food for thought Raaj.
>>
>> I could almost move the controls and logic of FormB back to the main
>> form --
>> if I did not want to keep it as an independent entity. The point being, I
>> only need one copy of it ever in the app. And the design of the main form
>> is
>> so clean, it merely controls the app, does the intial checks, hosts the
>> menustrip, etc.
>>
>> FormC on the other hand could indeed be called multiple times. But it too
>> is
>> only needed once for every iteration of FormB (FormC gets spawned by a
>> button click on FormB only). And the flow of data and control is one-way:
>> if
>> a certain search condition is met, either FormD gets shown or we fall
>> back
>> into FormB.
>>
>> FormD can only get created by FormC. Seems a remote possibility, but not
>> impossible that it could be created more than once (altho I can prevent
>> that).
>>
>> I'm not sure how you are envisioning FormB retrieving information from
>> FormD. May be a matter of semantics, I view it as FormD passing the
>> information back to FormB.
>>
>>
>>
>>
>> "Raaj" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>> > Earl,
>> >
>> > In my opinion rather than FormD notifying FormB of happening of an
>> > event, FormB should be retrieving this information from FormD (or
>> > through FormC per your example). That would make FormD independent and
>> > agnostic about notifying other objects (FormB in this case). To
>> > complicate things in MDI you can have multiple instances of FormB's,
>> > FormC's and FormD's at any given point.
>> > What we need to figure out is a way to pass information between these
>> > forms. Considering these, I would set the behavior of FormD (and FormC
>> > *may be* per your example) to modal instead of mdichild. That way FormB
>> > has reference to FormC->/FormD through which it would retrieve the
>> > necessary information the code would look something like this:
>> >
>> > FormD newMdiChild = new FormD();
>> > if (newMdiChild.ShowDialog(this) == DialogResult.OK)
>> > {
>> > this.SomeValue = newMdiChild.SomeProperty;
>> > //retreive other values ..so on
>> > }
>> >
>> >
>> > Raaj.
>> >
>> > Earl wrote:
>> >> I need to call a method on an owned child form, and am wondering if
>> >> the
>> >> best
>> >> way of doing this is to capture the Closing event of the form that
>> >> passes
>> >> control back to the form where I have the method. The structure is
>> >> like
>> >> so:
>> >>
>> >> frmMain (MDI, runs on app start) calls
>> >> frmB (MDI child), which in turn calls
>> >> frmC (MDI child), which in turn calls
>> >> frmD (MDI child).
>> >>
>> >> frmMain and frmB remain open while frmC and frmD are shown.
>> >>
>> >> frmC and frmD each close as they finish processing.
>> >>
>> >> Once the user makes selections, frmD then needs to pass control back
>> >> to
>> >> frmB
>> >> (right before closing) and fire a method that populates certain
>> >> controls
>> >> on
>> >> frmB. So my first thought is to add a handler to frmB to capture the
>> >> Closing
>> >> event of frmD, and use that handler to call the method to populate the
>> >> controls on frmB. Is there a better way, either easier, more
>> >> straightforward, or more efficient?
>> >

>



 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Base Method Calling Child Methods =?Utf-8?B?cmFuZHkxMjAw?= Microsoft C# .NET 1 4th Apr 2007 12:45 AM
Calling a method in one MDI child from another MDI child Earl Microsoft Dot NET Framework Forms 5 21st Dec 2006 08:30 AM
Calling method in child form from MDI main form Randy Microsoft C# .NET 5 25th Jun 2004 04:34 PM
Calling Method from child control h Microsoft C# .NET 1 17th Jun 2004 05:08 PM
Child object calling dynamic-parent method Kelmen Wong Microsoft C# .NET 2 23rd Dec 2003 12:21 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 09:20 PM.