MDI Child forms and menus...best practice?

  • Thread starter Thread starter Bob Rundle
  • Start date Start date
B

Bob Rundle

I working with an MDI application. This application has many child form
which have common menu operations.

For example ChildFormA supports Cut/Copy/Paste.

ChildFormB also supports Cut/Copy/Paste using completely different
semantics.

Now...

I could add an Edit menu to each child form. Each time the child form
becomes active the Edit menu is merged into the main form.

....Or...

I could have a single Edit menu on the Main form and somehow route the menu
events to the appropriate child form.

This routing business seems problematic however. Unless I want a big
if/then/else block in the mainform (I do not) then I will need to have a
base class form with common methods I can call from the main form.

Advice, Comments?

Regards,
Bob Rundle
 
Bob,
I think you're on the right track with creating base forms. The only other
thing I would add would be to create a single interface that all of your
base forms implement. Basically, create a different base form for each type
of form that handles the cut/copy/paste differently. The code below just
shows the declaration of an interface, with 2 base forms. Any form that
needs the functionality of the a base forms cut/copy/paste, just inherit
from. I added a declaration of Form1 to show this. Lastly, in the mdi form
when a menu item is clicked, just cast the ActiveMdiChild property of the
mdi to the IFormMenu interface. This is shown on the bottom.

public interface IFormMenu
{
void Cut();
void Copy();
void Paste();
}

public FormTypeA : System.Windows.Forms.Form, IFormMenu
{
void IFormMenu.Cut()
{
//implement code
}

void IFormMenu.Copy()
{
//implement code
}

void IFormMenu.Paste()
{
//implement code
}
}

public FormTypeB : System.Windows.Forms.Form, IFormMenu
{
void IFormMenu.Cut()
{
//implement code
}

void IFormMenu.Copy()
{
//implement code
}

void IFormMenu.Paste()
{
//implement code
}
}


public Form1 : FormTypeA
{
}

//inside mdi form
private void mnuCopy_Click(object sender, System.EventArgs e)
{
((IFormMenu)this.ActiveMdiChild).Copy();
}

private void mnuCut_Click(object sender, System.EventArgs e)
{
((IFormMenu)this.ActiveMdiChild).Cut();
}

private void mnuCopy_Paste(object sender, System.EventArgs e)
{
((IFormMenu)this.ActiveMdiChild).Paste();
}

I'm not claiming that this is the best practice, but I find it easy to
implement and it makes for not much code in your mdi.

HTH
 
Bob,
I forgot to add the "class" keyword for all of my class declarations in
the example I provided. Serves me right for using notepad...lol
 
Lateralus,

I really like this idea of the Edit menu interface. It will be much better
than having a form base class. My experience with form base classes is that
the form designer becomes very confused and eventually you simply start hand
coding the controls...you would have been better off copy/pasting the common
code onto all the forms!

Regards,
Bob Rundle


Lateralus said:
Bob,
I think you're on the right track with creating base forms. The only other
thing I would add would be to create a single interface that all of your
base forms implement. Basically, create a different base form for each type
of form that handles the cut/copy/paste differently. The code below just
shows the declaration of an interface, with 2 base forms. Any form that
needs the functionality of the a base forms cut/copy/paste, just inherit
from. I added a declaration of Form1 to show this. Lastly, in the mdi form
when a menu item is clicked, just cast the ActiveMdiChild property of the
mdi to the IFormMenu interface. This is shown on the bottom.

public interface IFormMenu
{
void Cut();
void Copy();
void Paste();
}

public FormTypeA : System.Windows.Forms.Form, IFormMenu
{
void IFormMenu.Cut()
{
//implement code
}

void IFormMenu.Copy()
{
//implement code
}

void IFormMenu.Paste()
{
//implement code
}
}

public FormTypeB : System.Windows.Forms.Form, IFormMenu
{
void IFormMenu.Cut()
{
//implement code
}

void IFormMenu.Copy()
{
//implement code
}

void IFormMenu.Paste()
{
//implement code
}
}


public Form1 : FormTypeA
{
}

//inside mdi form
private void mnuCopy_Click(object sender, System.EventArgs e)
{
((IFormMenu)this.ActiveMdiChild).Copy();
}

private void mnuCut_Click(object sender, System.EventArgs e)
{
((IFormMenu)this.ActiveMdiChild).Cut();
}

private void mnuCopy_Paste(object sender, System.EventArgs e)
{
((IFormMenu)this.ActiveMdiChild).Paste();
}

I'm not claiming that this is the best practice, but I find it easy to
implement and it makes for not much code in your mdi.

HTH

--
Lateralus [MCAD.Net]


Bob Rundle said:
I working with an MDI application. This application has many child form
which have common menu operations.

For example ChildFormA supports Cut/Copy/Paste.

ChildFormB also supports Cut/Copy/Paste using completely different
semantics.

Now...

I could add an Edit menu to each child form. Each time the child form
becomes active the Edit menu is merged into the main form.

...Or...

I could have a single Edit menu on the Main form and somehow route the menu
events to the appropriate child form.

This routing business seems problematic however. Unless I want a big
if/then/else block in the mainform (I do not) then I will need to have a
base class form with common methods I can call from the main form.

Advice, Comments?

Regards,
Bob Rundle
 
Bob,
I looked into this option. Basically what you do is in all of your "base
forms" you create a main menu, add the cut/copy/paste and the functionality
is behind each base form. Then, from within your base forms you need to call
the following:

//assume the menu's name in your base form is mnuName
this.MdiParent.Menu.MergeMenu(this.mnuName);

this will merge your menu to the mdi menu. If you have a menu item at the
top level displayed as "File" and you have the same in your base form, you
will see two items at the top level labeled ast "File". So basically on your
mdi menu don't declare your File | cut/copy/paste. Just put them in your
base forms.

HTH

-- Lateralus [MCAD.Net]
 
Back
Top