2014-10-26 1 views
1

У меня есть форма с кнопкой «Поиск». Когда я нажимаю его, открывается другая форма для поиска элемента. Когда пользователь нажимает на X в этой второй форме, чтобы закрыть его, я действительно не хочу, чтобы он закрывался, я просто хочу сделать его невидимым (по secondForm.visible = false).Как правильно переопределить метод OnFormClosing() в C#

Я нашел, что мне нужно только переопределить метод OnFormClosing(), и я сделал это в классе формы, но он вообще не выполняется. Я знаю, что это не выполняется, потому что когда в следующий раз нажата кнопка «Поиск» (вместо do new SecondForm() она пытается просто сделать secondForm.visible = true) Я получаю исключение, в котором говорится, что я не могу работать с удаленным объектом (secondForm) или что-то типа того. Таким образом, вторая форма только что была закрыта, а не видна.

В этот момент я начинаю думать то, что мне нужно назначить, каким-то образом (который я obviusly не знаю), этот новый метод переопределение кнопки X.

EDIT:

Это мой перекрытый метод во втором от класса:

protected override void OnFormClosing(FormClosingEventArgs e) 
    { 
     base.OnFormClosing(e); 

     if (e.CloseReason == CloseReason.WindowsShutDown) return; 

     this.Visible = false; 
    } 

Это то, что я делаю, когда кнопка «Поиск» щелкают:

private void btnSearch_Click(object sender, EventArgs e) 
    { 
     if (subFormCreated) 
      subFormSearch.Visible = true; 
     else 
      initializeSubFormSearch(); 
    } 

    private void initializeSubFormSearch() 
    { 
     subFormSearch = new SubForm(listaPersonas, actualMostrado); 
     subFormSearch.Show(); 
     subFormCreated = true; 
    } 

Наконец, исключение составляет то, что я получаю ObjectDisposedException. Точное сообщение - это что-то вроде (я не знаю, правильно ли я его перетаскиваю) ObjectDisposedException was unhandled. Cannot get access to the deleted object. Name of the object: SubForm.

+0

Пожалуйста, укажите точный код и точное сообщение об исключении. – CodeCaster

ответ

1

Вам действительно не нужно ничего переоценивать. Просто обработайте событие FormClosing и установите e.Cancel = True. Плюс сделать вашу форму невидимой в том же обработчике. В первой форме сделайте объект уровня класса вашей второй формы и вызовите его ShowDialog() при нажатии кнопки поиска. Наконец убедитесь, что ваш OK и Отмена кнопок имеют свой DailogResult набор свойств соответственно. Примерно это будет выглядеть следующим образом:

class Form1 
{ 
    private Form2 dlg; 

    private void btnSearch_Click(object sender, EventArgs e) 
    { 
     if(dlg==null) dlg = new Form2(); 
     dlg.ShowDialog(this); 
    } 
} 

class Form2 
{ 
    private void Form2_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     e.Cancel = true; 
     this.Hide(); 
    } 
} 
+0

Я понял это: D, но в любом случае это решение означает, что всегда я запускаю основную форму, я буду создавать вторую форму, даже если мне это не нужно, не так ли? Поэтому я думаю, что буду принимать потребление лишних ресурсов. Что об этом? Стоит ли это того? – Drumnbass

+0

@Drumnbass: Я действительно не буду беспокоиться о сохранении этих нескольких КБ памяти, учитывая чрезмерное количество оперативной памяти, которую мы имеем на сегодняшних машинах. Тем не менее, я вношу изменения в вышеуказанный код, чтобы решить эту проблему. – dotNET

+0

Уверен, я предположил, что это всего лишь несколько килобайт памяти, но заметьте, что я все еще новичок программист (просто студент), и я начну получать хорошие практики с тех пор;) – Drumnbass

2

Вы не остановить его от закрытия, Вы забыли установить свойство e.Cancel к истинной. Правильный код:

protected override void OnFormClosing(FormClosingEventArgs e) { 
    if (e.CloseReason != CloseReason.WindowsShutDown) { 
     this.Visible = false; 
     e.Cancel = true; 
    } 
    base.OnFormClosing(e); 
} 

С дополнительными деталями, которые вы никогда не хотите избежать вызова base.OnFormClosing(), когда операционная система завершает работу, и вы называете это после ваших настроек так, что клиентская программа при необходимости может отменить ваше решение.

сделать его еще более упругим, подписавшись на FormClosed событие в главном классе, так что вы знаете что нужно переменная subFormCreated быть установлен в ложной. Обратите внимание, что вам не нужна эта переменная, вы можете просто вернуть переменную subFormSearch к нулю. Итак, примерно:

private void displaySubFormSearch() { 
    if (subFormSearch != null) { 
     subFormSearch.WindowState = WindowState.Normal; 
    } 
    else { 
     subFormSearch = new SubForm(listaPersonas, actualMostrado); 
     subFormSearch.FormClosed += delegate { subFormSearch = null; }; 
    } 
    subFormSearch.Show(); 
} 

С дополнительной информацией, которую вы гарантируете, что вы восстановите окно, если пользователь сведёт к минимуму его ранее. Теперь он твердый. Вам могут потребоваться свойства для передачи обновленных listaPersonas и actualMostrado, это не ясно.