Очень странная ошибка при использовании Show Dialog на C # Winform - PullRequest
2 голосов
/ 02 августа 2009

Я создал 2 формы в VS Studio 2008 Express Edition и объявил их как общедоступную статическую в основном файле program.cs

Я просто хочу переключиться между двумя формами с помощью ShowDialog и Close, но при попытке закрыть вторую форму и снова открыть первую форму с помощью showdialog, он говорит, что я не могу использовать showDialog, когда форма уже видна, тогда как это не так правда, так как я закрыл его, прежде чем показывать вторую форму.

Он попросил меня установить для свойства visible значение false до использования showdialog, поэтому я сделал это

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

Но тогда говорится, что я не могу использовать ShowDialog, потому что форма уже показана в режиме диалога, и я должен закрыть ее. Поэтому я сделал то, что он спросил

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

Но он все еще делает вид, что форма уже открыта с помощью ShowDialog!

Это ошибка в моей проге или в Winform?

Обновление: это весь код, который я опубликовал в 5-м ответе (я хочу использовать showdialog, а не показывать, потому что у меня может быть 3-я форма в фоновом режиме, к которой я не хочу, чтобы пользователь имел доступ):

  [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();
  }

Я пытался использовать Hide, как это было предложено, но он тоже не работает. Это целая программа, то, что я хочу сделать, очень просто: у меня есть две формы, изначально созданные в программе, с одной кнопкой на каждой форме, чтобы закрыть себя и открыть другую. Я поместил всю логику в program.cs ниже:

  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();
          }
      }
  }

Ответы [ 5 ]

5 голосов
/ 02 августа 2009

Это ошибка в вашей программе. Когда у вас есть два экземпляра формы (назовите их A и B), вы, очевидно, не сможете непрерывно показывать один из другого, используя ShowDialog. Если бы вы могли это сделать, это означало бы, что A показывает B модально, а B затем показывает A модально, а A затем показывает B модально и т. Д. Это будет похоже на строительство дома с двумя кирпичами, где вы просто продолжаете брать нижний кирпич и поместив его поверх другого.

Лучшее решение - не создавать статичные формы, а просто создавать новые экземпляры каждой формы по мере необходимости. Ваше второе лучшее решение - использовать Show вместо ShowDialog; если у вас есть только одна из этих форм, отображаемых одновременно, ShowDialog не имеет смысла.

Статические формы почти всегда плохая идея (и я вежливо отношусь к "почти"). Если создание ваших форм занимает много времени, вы должны определить, какой ресурс требует столько времени для загрузки и кэшировать его как статический объект, вместо того чтобы пытаться кэшировать всю форму как статическую.

4 голосов
/ 02 августа 2009

Это из MSDN:

Когда форма отображается как модальная диалоговое окно, нажав кнопку Закрыть (кнопка с крестиком на верхний правый угол формы) вызывает форма, которая будет скрыта и Свойство DialogResult должно быть установлено в DialogResult.Cancel. В отличие от немодального формы, метод Close не вызывается .NET Framework, когда пользователь нажимает кнопку закрытия формы диалоговое окно или задает значение Свойство DialogResult. Вместо форма скрыта и может быть показана снова без создания нового экземпляра диалоговое окно. Потому что форма отображается как диалоговое окно не закрыто, вы должен вызвать метод Dispose форма, когда форма больше не нужна по вашей заявке.

Так что, как только вы показываете форму, используя ShowDialog, и теперь хотите закрыть ее, просто дайте ей вернуть DialogResult.Cancel. Это скроет (это все еще будет в памяти) вашу первую форму. Теперь вы можете вызвать ShowDialog на второй форме. Опять же, если вы хотите переключиться на первую форму, тогда пусть вторая форма возвращает DialogResult.Cancel, а теперь просто вызовите ShowDialog для первой формы.

1 голос
/ 02 августа 2009

Я думаю, вам действительно следует относиться к модальным диалогам как к вызовам методов, и пытаться использовать результат Call to ShowDialog, чтобы определить, что вы хотите делать дальше? если у вас есть требование переключаться между диалогами, вы должны использовать какой-то результат (возможно, просто DialogResult, смотрите мой пример) или открытое свойство диалога, чтобы определить, нужно ли вам показывать другой диалог, если вам нужно вызвать один модальный диалог из с другой стороны, вы должны думать об этом как о пачке форм, которые эффективно (даже если вы делаете одну невидимой перед вызовом другой) помещают одну на другую. Вы действительно хотите минимизировать сложение форм.

Это немного надуманный пример, но каждая форма здесь просто имеет одну кнопку с DialogResult, установленным в OK.

[STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        bool exit = false;
        while (true)
        {
            if (exit) break;
            using (Form1 frm = new Form1())
            {
                switch(frm.ShowDialog())
                {
                    case DialogResult.OK:
                        break;
                    default:
                        exit = true;
                        break;
                }   
            }
            if(exit) break;
            using (Form2 frm = new Form2())
            {
                switch(frm.ShowDialog())
                {
                    case DialogResult.OK:
                        break;
                    default:
                        exit = true;
                        break;
                } 
            }

        }

    }

для выхода просто нажмите красную кнопку закрытия (x).

1 голос
/ 02 августа 2009

Попробуйте использовать Hide () вместо Close (). У меня была похожая проблема в прошлом, и Hide () работал на меня.

0 голосов
/ 02 августа 2009

Проверьте разницу между Close и Hide. И разница между Show и ShowDialog.

Мне не совсем понятно, чего вы хотите достичь; Вы только (частично) описываете, что вы сделали в коде, и симптом вашей проблемы. Не могли бы вы описать, что вы пытаетесь сделать?

Если ваша цель состоит в том, чтобы в главном окне отображались два диалоговых окна, в которых одновременно может быть виден только один из двух, то, возможно, существуют более эффективные решения, чем использование двух статических (= глобальных) публичных Form экземпляров, которые вы показываете, используя ShowDialog.

Вы думали использовать один диалог Form для этого, который просто меняет его внешний вид в зависимости от ситуации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...