Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Very strange bug when using Show Dialog on C# Winform

I have created 2 forms in VS Studio 2008 Express Edition and declare them with public static in main program.cs file

I just want to switch between the two forms with ShowDialog and Close but when trying to close the second form and open the first form again with showdialog it says I cannot use showDialog when the form is already visible, whereas it isn't true since I closed it before to show the second form.

It asked me to set the form visible property to false before using showdialog, so I did it

    internal static void CloseSecondForm(FirstForm FirstForm)
    {
        FirstForm .Close();
        SecondForm.Visible = false;
        SecondForm.ShowDialog();
    }

But then it says I cannot use ShowDialog because the form is already shown in Dialog Mode and that I must close it. So I did what it asked

    internal static void CloseSecondForm(FirstForm FirstForm)
    {
        FirstForm .Close();
        SecondForm.Visible = false;
        SecondForm.Close();
        SecondForm.ShowDialog();
    }

But it still pretends that the form is already opened with ShowDialog !

Is this a Bug in my prog or in Winform ?

Update: this is the whole code I posted in 5th answer (I want to use showdialog and not show because I may have a 3rd form in Background that I don't want the user to access):

  [STAThread]
  static void Main()
  {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Form1 = new Form1();
      Form2 = new Form2();
      Form1.ShowDialog();
      Application.Run();

  }

  // called from Form1 BUTTON
  internal static void ShowForm2(Form1 Form1)
  {
      Form1.Hide();
      Form2.ShowDialog();
  }

  // called from Form2 BUTTON
  internal static void ShowForm1(Form2 Form2)
  {
      Form2.Hide();
      Form1.ShowDialog();
  }

I tried with Hide as suggested but it doesn't work either. This is the whole program, what I want to do is very simple: I have two forms initially created in program with one button on each form to close self and open the other. I put all the logic in program.cs below:

  using System;
  using System.Windows.Forms;

  namespace twoforms
  {
      static class Program
      {
          /// <summary>
          /// The main entry point for the application.
          /// </summary>
          /// 
          public static Form1 Form1;
          public static Form2 Form2;

          [STAThread]
          static void Main()
          {
              Application.EnableVisualStyles();
              Application.SetCompatibleTextRenderingDefault(false);
              Form1 = new Form1();
              Form2 = new Form2();
              Form1.ShowDialog();
              Application.Run();

          }

          // called from Form1 BUTTON
          internal static void ShowForm2(Form1 Form1)
          {
              Form1.Hide();
              Form2.ShowDialog();
          }

          // called from Form2 BUTTON
          internal static void ShowForm1(Form2 Form2)
          {
              Form2.Hide();
              Form1.ShowDialog();
          }
      }
  }
like image 978
programmernovice Avatar asked Dec 13 '22 03:12

programmernovice


2 Answers

This is a bug in your program. When you have two instances of a form (call them A and B), you obviously cannot continually show one from the other using ShowDialog. If you could do this, it would mean that A shows B modally, and B then shows A modally, and A then shows B modally etc. This would be like building a house with two bricks, where you just keep taking the bottom brick and placing it on top of the other.

Your best solution is to not make these forms static, and instead just create new instances of each form as you need them. Your second-best solution is to use Show instead of ShowDialog; if you only have one of these forms showing at a time anyway, ShowDialog has no purpose.

Static forms are almost always a bad idea (and I'm being polite about "almost"). If your forms are taking a long time to create, you should identify what resource is taking so long to load and cache that as a static object, instead of trying to cache the entire form as static.

like image 63
MusiGenesis Avatar answered Jan 11 '23 23:01

MusiGenesis


This is from MSDN:

When a form is displayed as a modal dialog box, clicking the Close button (the button with an X at the upper-right corner of the form) causes the form to be hidden and the DialogResult property to be set to DialogResult.Cancel. Unlike modeless forms, the Close method is not called by the .NET Framework when the user clicks the close form button of a dialog box or sets the value of the DialogResult property. Instead the form is hidden and can be shown again without creating a new instance of the dialog box. Because a form displayed as a dialog box is not closed, you must call the Dispose method of the form when the form is no longer needed by your application.

So once you show a form using ShowDialog and you now want to close it, just let it return DialogResult.Cancel This will hide (it will still be in memory) your first form. Now you can call ShowDialog on your second form. Again, if you want to switch to first form then let the second form return DialogResult.Cancel and now just call ShowDialog on first form.

like image 41
P.K Avatar answered Jan 11 '23 23:01

P.K