2010-05-10 6 views
0

У меня есть основная форма MDI. На нем у меня есть форма, и я хочу, чтобы она показывала окно сообщения перед закрытием (спрашивая пользователя, сохранять ли изменения).Как предотвратить закрытие основной формы MDI у ребенка MDI

До сих пор так хорошо, однако я обнаружил, что закрытие основной формы MDI не приводит к событию FormClosing дочернего события MDI. Я решил, что позвоню MdiChild. Закрыть() в событии FormClosing основного события MDI (которое поднимается). Этот шов для работы, однако он вызывает проблему ...

В появившемся ящике сообщений я предлагаю пользователю сохранять изменения, а не сохранять изменения и отменять закрытие. Обычно это прекрасно работает, однако я не могу найти способ отменить событие FormClosing MDI main. Есть ли элегантный способ сделать это?

EDIT: Я решил это, выбросив исключение (когда пользователь решил отказаться от процедуры закрытия), которая попала в событие FormClosing MDI main. Таким образом, я знаю, когда мне нужно отменить событие FormClosing в MDI main, и эти швы хорошо работают ... Однако я просто не могу поверить, что этот «hax» - единственный способ сделать это. Наверняка есть лучший способ?

ответ

2

Я полагаю, что вы отмените закрытие на дочерней форме, когда пользователь голосует, чтобы отменить закрытие?

В этом случае я бы с этой основной формой близкой

private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if (e.CloseReason == CloseReason.UserClosing) 
    { 
     foreach (Form frm in this.MdiChildren) 
     { 
      frm.Close(); 
     } 
    } 
    e.Cancel = (this.MdiChildren.Length > 0); 
} 
+0

Нет, не делайте этого так, потому что вы, вероятно, захотите остановиться, как только пользователь нажмет «Отмена» в приглашении «Сохранить изменения». Вы не хотите, чтобы пользователю приходилось циклически перебирать каждую форму в этот момент, и этот код делает это. Вместо этого, после вызова Close(), установите флажок frm.IsDisposed. Если это неверно, форма по какой-то причине не может закрыться, и вы должны установить e.Cancel = true и выйти из вашего цикла foreach. Таким образом, как только пользователь нажимает «Отмена», вся операция останавливается. –

1

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

И если все дети образуют «голос» для закрытия, то вы закрываете все это, иначе вы ничего не закрываете.

1

При закрытии главной формы MDI, все дочерних Закрыть события называется первым так, при вызове frm.Close() на петле Еогеаспа , Закрыть события для ребенка снова вызываются (я не знаю, почему, если они должны быть уже закрыты).

Предложение ho1 работало довольно хорошо для меня. Вот мой цикл модифицирована Еогеаспа (ClosableMDIChildForm представляет собой интерфейс, который содержит метод IsOkToClose()):

foreach (ClosableMDIChildForm cmdif in this.MdiChildren) 
{ 
    if (!cmdif.IsOkToClose()) 
    { 
     e.Cancel = true; 
     ((Form)mdifc).Focus(); 
     break; 
    } 
} 

Очевидно, что this.MdiChildren форма должна реализовывать интерфейс ClosableMDIChildForm. Логика решить, нормально ли закрыть окно, идет в реализации IsOkToClose().