2010-04-22 59 views
3

我們希望在某些情況下可以阻止標題欄中關閉按鈕的操作。問題是這是一個MDI應用程序,似乎我們將不得不在每個表單中添加代碼以取消在Closing事件處理程序中的操作。看來孩子們是第一個接受這個事件的人。沒有辦法在一個地方添加代碼來取消關閉操作。歡迎關於如何將關閉事件傳播給子表單的信息。有沒有簡單的方法來做我們想做的事?如何處理來源處的關閉(大X)按鈕?

+2

你可以繼承的形式,編寫代碼在它關閉,然後使用該表而不是爲你的孩子。 – 2010-04-22 17:11:07

+0

@Michael。困難在於它是一個遺留應用程序,並且已經實現了很多表單。改變繼承的類並不難。問題是每個類都有處理'Closing'事件。我可以將它們綁定到從繼承類中調用的另一個自定義事件。我仍然希望有一個更好的解決方案,但這是迄今爲止最好的。 – 2010-04-22 17:47:45

回答

3

Windows提供了一種方法來做到這一點,你可以修改系統菜單。提供良好的反饋,關閉按鈕實際上看起來被禁用。您可以在系統菜單中禁用SC_CLOSE命令。最好用樣品的形式表現出來,通過刪除按鈕就可以開始:

using System.Runtime.InteropServices; 
... 

public partial class Form1 : Form { 
    public Form1() { 
     InitializeComponent(); 
     button1.Click += new EventHandler(button1_Click); 
    } 

    private bool mCloseEnabled = true; 
    public bool CloseEnabled { 
     get { return mCloseEnabled; } 
     set { 
      if (value == mCloseEnabled) return; 
      mCloseEnabled = value; 
      setSystemMenu(); 
     } 
    } 

    protected override void OnHandleCreated(EventArgs e) { 
     base.OnHandleCreated(e); 
     setSystemMenu(); 
    } 
    private void setSystemMenu() { 
     IntPtr menu = GetSystemMenu(this.Handle, false); 
     EnableMenuItem(menu, SC_CLOSE, mCloseEnabled ? 0 : 1); 
    } 
    private const int SC_CLOSE = 0xf060; 
    [DllImport("user32.dll")] 
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool revert); 
    [DllImport("user32.dll")] 
    private static extern int EnableMenuItem(IntPtr hMenu, int IDEnableItem, int wEnable); 

    private void button1_Click(object sender, EventArgs e) { 
     CloseEnabled = !CloseEnabled; 
    } 
} 
+0

這就是我最終使用的解決方案。它效果很好。謝謝。 – 2010-04-22 19:35:56

1

邁克爾已經寫在評論的答案(只是在這裏添加到答案):

創建一個單一的BaseFormsClass,你重寫的行爲,然後從新BaseFormsClass繼承你的類。

+0

我剛回答Michael。 – 2010-04-22 17:48:46

+0

您可以嘗試攔截WM_CLOSE窗口消息。但除非你真的有成千上萬的現有表格,我認爲基礎類方法將是最簡單/最快速的方法。 – Foxfire 2010-04-22 18:15:15

相關問題