2011-02-28 41 views
2

搜索谷歌和stackoverflow後我無法找到一個答案,幫助我在我的情況。我有一個開始菜單(表單)的應用程序。當用戶按下(任何)表單的X(關閉)時,我將重新加載開始菜單。現在,當這個(菜單)表單被關閉時,我想檢查並通知用戶,如果用戶按下取消,任何現在隱藏的表單處於編輯模式(有或沒有未保存的更改),我想顯示該表單並停止應用程序關閉。現在我的問題是如何停止應用程序停止在其他窗體的代碼。我重寫了調用this.close的子表單的dispose方法,以便ok/cancel messagebox顯示,但是在MB之後,開始菜單仍然會關閉程序。我應該尋找一種處理這些東西的不同方法,或者是否有方法或事件處理程序來修改,以便此/ \可以工作?c#取消應用程序關閉,如果隱藏窗體有未保存的更改

編輯: 好的,這裏按代碼的順序調用。我哪裏出錯了?

private void Menu_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     Global.Forms.Remove(this); 
     if (!Global.Clean_Forms()) 
     { 
      e.Cancel = true; 
      Global.Forms.Add(this); 
     } 
    } 

public static void Clean_Forms() 
    { 


     foreach (Form f in Forms) 
      { 
       if (f is Menu) 
       { 
        //do nothing 
       } 
       else 
       { 
        if (!f.IsDisposed) 
        { 


         f.Close(); 
        } 

       } 

      } 
     if (Forms.Count != 0) 
     { 
      isClean = false; 
      /* String a = ""; 
      foreach (Form f in Forms) 
      { 
       a += f.ToString() + ": "; 
      } 
      MessageBox.Show(a);*/ 
     } 
     else 
     { 
      isClean = true; 
     } 

    } 

然而,這不起作用,應用程序只是關閉。

隨機

形式

private void persoon_form_FormClosing(object sender, FormClosingEventArgs e) 
    { 

     if (editing) 
     { 
      DialogResult dr; 
      dr = MessageBox.Show("uw wijzigingen gaan verloren. Doorgaan?", "sluiten", MessageBoxButtons.OKCancel); 
      if (dr == DialogResult.Cancel) 
      { 
       e.Cancel = true; 


      } 
      else if (dr == DialogResult.OK) 
      { 
       Global.size = this.Size; 
       Global.position = this.Location; 
       Global.Forms.Remove(this); 
       Form f = Global.menu(); 
       f.Show(); 
       this.Dispose(); 
      } 
     }//somethingelse} 

EDIT的閉合事件處理程序:@cody灰色的OnClose改變並且仍然clean_form沒有影響,(不應該在窗體的Closing事件在MessageBox無論如何所示造成的嗎?沒有)

回答

0

我想我想通了!我改變了兩件事。 1我確信我沒有在任何地方調用此函數,因爲這會導致處理(不關閉)任何子表單,因此不會調用任何關閉事件。 2.檢查主菜單是否可以關閉生成的集合時的foreach循環是修改後的錯誤。因此,我確保它按照正確的順序thnx科迪灰色關閉指向我在正確的方向:

Stack<Form> stack = new Stack<Form>(); 
      foreach (Form f in Forms) 
      { 
       if (f is Menu) 
       { 
        //do nothing 
       } 
       else 
       { 
        if (!f.IsDisposed) 
        { 


         stack.Push(f); 
        } 

       } 

      } 
      for (int i = 0; i < stack.Count; i++) 
      { 
       Form temp = stack.Pop(); 
       temp.Close(); 
      } 
+1

不客氣。我不禁注意到,你「固定」的兩件事是我無法知道的東西在一開始就是錯誤的。你沒有告訴我你在代碼中的其他地方調用了表單對象的Dispose方法(沒有理由這麼做,而是使用Close方法)。你也沒有提到你正在修改'foreach'循環中的表單集合(也是一個壞主意;如果你需要這樣做,可以使用''''循環或單獨的'List ')。不過,我很高興聽到您找到了可以接受的解決方案。 –

7

你不應該這樣做在Dispose方法。相反,請嘗試處理FormClosing event

此事件發生之前被關閉的形式,讓你可以檢查你需要的任何狀態,並通過設置e.Cancel爲True取消關閉,如果必要的。

例如:

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

    // Check to see if the user is allowed to close this form 
    if (!allowClose) 
    { 
     // Prevent this form from being closed 
     MessageBox.Show("This form cannot be closed yet!"); 
     e.Cancel = true; 
    } 
} 
+0

是啊我已經嘗試過,但該事件不會因爲某些原因被解僱。我搜索了這個,我提出的解決方案是在dispose事件中調用this.close,這樣我就可以執行e.cancel事情。問題是。儘管e.cancel爲true(該表單不關閉),但第一種形式(Application.Run(new Menu());)仍然關閉。當關閉所有表單時,無論如何都會被丟棄 – Daanvl

+1

@Daanvl:當Dispose被調用的時候(以及任何代碼放在裏面的時候),取消表單關閉太遲了。我不知道你在網上找到了哪個解決方案,但這種解決方法永遠不會奏效。你需要找出一種防止* main *表單關閉的方法。重寫它的'OnFormClosing'方法來做到這一點。 –

+0

窗體是一個自定義窗體列表(添加,刪除,僅用於跟蹤打開的窗體)(Global是單例類型的類)。但主要問題仍然存在,如果我不能使用dispose事件,我怎麼能保證這個onformclosing事件被解僱?在行f.close();表單被破壞,但沒有關閉的事件代碼得到執行 – Daanvl

相關問題