WinForm, располагающая суб-форму при ее удалении - PullRequest
0 голосов
/ 01 июня 2009

У меня есть форма, которая может открыть вложенную форму (с ShowDialog). Я хочу убедиться, что суб форма размещается правильно, когда основная форма готова. Я попытался добавить подчиненную форму к элементу components основной формы, но в данный момент я получил ArgumentNullException.
Я знаю, что могу сам создать экземпляр components, но разве это не опасно? Однажды я добавлю компонент в представлении конструктора, и он сгенерирует строку new Container() в файле designer.cs, и я никогда не узнаю, что у меня есть два экземпляра компонентов, работающих вокруг кучи.
Есть ли более простой способ убедиться, что суб форма удалена?

РЕДАКТИРОВАТЬ - переместил мое решение в ответ

Ответы [ 4 ]

3 голосов
/ 01 июня 2009

Если вы используете форму в showdialog, можно предположить, что после того, как вы получили результат, вы можете разместить форму там?

using(MyDialog dlg = new MyDialog())
{
   result = dlg.ShowDialog();
}
1 голос
/ 01 июня 2009

Обычно вы не можете переопределить методы Dipose формы, поскольку они уже определены в файле Form.Designer.cs. Есть небольшая хитрость, как добавить свою собственную логику размещения в форму.

Используя следующий класс:

public class Disposer : Component
    {
        private readonly Action<bool> disposeAction;               

        public Disposer(Action<bool> disposeAction)
        {
            this.disposeAction = disposeAction;
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            this.disposeAction(disposing);
        }

        public static Disposer Register(ref IContainer container, Action<bool> disposeAction)
        {
            Disposer disposer = new Disposer(disposeAction);
            if (container == null)
                container = new System.ComponentModel.Container();

            container.Add(disposer);
            return disposer;
        }
    }

Сохраните список подчиненных форм и добавьте следующую строку в конструктор основной формы:

Disposer.Register(ref this.components, this.MyDisposeAction);

Когда ваша основная форма будет удалена, все ваши подчиненные формы также будут удалены, например ::

private void MyDisposeAction(bool disposing)
{
  if (disposing)
  {
    foreach (var subForm in this.subForms)
    {
      subForm.Dispose(disposing);
    }
  } 
}
0 голосов
/ 29 июня 2009

Мой текущий обходной путь:
Я добавил свойство Components в форму и использую его для доступа к коллекции

private IContainer Components{    get { return components ?? (components = new Container());}}
0 голосов
/ 01 июня 2009

Согласно MSDN , модальные формы, вызываемые с помощью ShowDialog(), не удаляются автоматически, и ответственность за их устранение лежит на разработчику:

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

Здесь уместно указать «когда форма больше не нужна». В вашем случае вам, похоже, нужна форма для последующих действий, поэтому перенос вызова ShowDialog() в конструкцию using не будет служить цели.

Я бы посоветовал избавиться от диалога в методе Dispose вашей основной формы или как можно раньше:

protected override void Dispose(bool disposing)
{
  if (disposing && (components != null))
  {
    components.Dispose();
  }
  // dlg is a variable of type Form2(the dialog)
  if (dlg != null)
  {
    dlg.Dispose();
    dlg = null;
  }
  base.Dispose(disposing);
}
...