Welcome to WindowsClient.net | My Blog | Sign in | Join

Windows Client Videos

How Do I: Manage MDI and SDI Windows Forms

In this video Pat Tormey shows how to manage forms both as Multiple Document Interface (MDI) and Single Document Interface (SDI) with notes and tips for handling single and multiple instances, menus, and even a bit on the MDI for Template.

By: Pat Tormey

Comments

blackjack2150 said:

Hi.

You display the pink form by calling this method as it was static:

FormPink.Show()

But this doesn't work in C#. I looked at the sample code, and the C# version does not have the same functionality as the VB.NET one. In the C# version, the pink and blue form behave exactly the same. The pink form can have multiple instances, which is contrary to what the tutorial says.

Could you please explain the different behavior? Why is FormPink.Show() valid in VB.NET and it isn't in C#? And is there a way to make the pink form appear only once in C#? (other than implementing a singleton pattern)

Thanks!

# July 22, 2008 8:03 AM

blackjack2150 said:

Can any of you VB experts explain, please?

# August 7, 2008 3:58 AM

totallyweb said:

Yes you can get the same behavior as in VB.Net!

public partial class MDIParent1 : Form

   {

       private int childFormNumber = 0;

      private  FormPink frm;   // define the frm as a private member here

     .

     .

     .

, then modify the button click event as follows.

private void button2_Click(object sender, EventArgs e)

       {

               frm = new FormPink();  //  Create the frm object here

               frm.MdiParent = this;

               frm.Show();

       }

Then you get the same behavior as the VB code!  Try it!

# August 14, 2008 11:58 PM

totallyweb said:

Sorry, the above code is not quite right.  It was a late night submission.  Here is the corrected version.

publlic partial class MDIParent1 : Form

  {

      private int childFormNumber = 0;

     private  FormPink frm = null;   // define the frm as a private member here

    .

    .

    .

    private void CloseAllToolStripMenuItem_Click(object sender, EventArgs e)

       {

           foreach (Form childForm in MdiChildren)

           {

               childForm.Close();

            }

           frm = null; // set the object to null

       }

      .

      .

      .

, then modify the button click event as follows.

private void button2_Click(object sender, EventArgs e)

{

         if (frm == null)

        {

              frm = new FormPink();  //  Create the frm object here

              frm.MdiParent = this;

              frm.Show();

       }

}

and write a FormClosing event for the pink form to set frm to null.

private void FormPink_FormClosing(object sender, FormClosingEventArgs e)

       {

           MDIParent1 mdi = (MDIParent1) this.MdiParent;

           mdi.frm = null;

       }

Then you get the same behavior as the VB code!  Try it!

# August 15, 2008 10:11 AM

totallyweb said:

This line of code is NOT necessary as the FormClosing event will do this for us.

frm = null; // set the object to null

There may be alternate approaches, but this is a way to go!

# August 15, 2008 10:27 AM

totallyweb said:

Final comments!  One last typo.  It should read:

 public  FormPink frml;   // define the frm as a public member here

or else the compiler will complain about:

mdi.frm = null;

You don't have to set frm = null as the C# compiler will do that for you.  As a best practice it is better to leave frm as a private variable and add just below it the code:

public void Reset () { frm = null;}

Theh in FormPink.cs change

mdi.frm = null;

to

mdi.Reset();  // calsl the public method Reset() to set frm = null

# August 15, 2008 3:01 PM

Pat Tormey said:

Hey TotallyWeb,

Thanks for helping out..

I simply didn't see the message.

BlackJack2150,  Instancing is really just a scoping thing. If it's still aroung in scope you can just show it again. VB shortcuts this to make all of us old VB-ers stop complaining (g)

Sorry for the confusion

Pat Tormey

New Hampshire USA

# August 18, 2008 9:23 AM

blackjack2150 said:

Ok, thanks guys. I was in a bit of confusion because I had little exposure to VB in the past and I thought that VB.NET and C# are virtually equivalent (except for pointers). So now I learned that there are other subtle differences too.

# August 19, 2008 2:44 AM

totallyweb said:

If you want to see the equivalent code in VB.Net that corresponds to the code I wrote in C#.net, here it is!

Public Class Form1

   Private frm As FormPink = Nothing   '<--    private  FormPink frm = null;

   Public Sub Reset()                              '<--   public void Reset () { frm = null;}

       frm = Nothing

  End Sub

.

.

.

   Private Sub ButtonPinkForm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)  Handles ButtonPinkForm.Click

         If frm Is Nothing Then     '  <--   if (frm == null)

           frm = New FormPink      '          {

           frm.MdiParent = Me      '                frm = new FormPink();

           frm.Show()                    '                frm.MdiParent = this;

         End If                              '                frm.Show();

  End Sub                                  '          }

  And in FormPink handle the FormClosing event!

Public Class FormPink

   Private Sub FormPink_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing

       Dim mdi As Form1 = CType(Me.MdiParent, Form1)

       mdi.Reset()

   End Sub

End Class

That's it in a nutsell!  Although the two languages are distinct, the MSIL (Microsoft Intermediate Language) code that will be generated will be pretty darn close.

# August 24, 2008 10:01 PM

edub45660 said:

blackjack2150 - This was posted months ago, so I am sure that you have moved on to other challenges. Here is a near replication of the VB code used in the video, in C#. Replace the code in your main form with the followiing:

public partial class Form1 : Form

   {

       private PinkForm pink = new PinkForm();     // creates a single instance of the pink form

       public Form1()

       {

           InitializeComponent();

       }

       private void btnBlue_Click(object sender, EventArgs e)

       {

           BlueForm blue = new BlueForm();         // creates a new instance on each button click

           blue.MdiParent = this;                  // tell the child form who its parent is

           blue.Show();    

       }

       private void btnPink_Click(object sender, EventArgs e)

       {

           pink.MdiParent = this;                  // tell the child form who its parent is

           pink.Show();

       }

   }

# December 6, 2008 3:40 PM

msammer said:

How about an MDI type strategy with WPF. Apparently it is not favored in WPF, correct?  How to accomplish similar affect in WPF.  The proposal to use a "Tab" control will simply not provide adequate user  functionality.  I understand I can use "owner/owned' properties. How can I restrict the owned Windows MaxBounds to ie within a Stack Panel or the owner Window. Could use Window Forms, but would much prefer to use the "Newest" and "Best_est" approach. Did I miss another suitable option in WPF?

By the way, have thoroughly enjoyed your "How To Videos!"

Thanks, MSammer.

# February 5, 2009 3:27 PM