使用 .NET 開發 MDI 模式的視窗應用程式是非常容易達成的,透過視窗屬性設定 IsMdiContainer 為 true 就可以將子視窗的 MdiParent 屬性指向自己,這是最簡易的 MDI 設計方式。以下以Visual Studio 2005 示範如何建立一個 MDI 模式的視窗程式。
一、基本做法
首先在 Visual Studio 2005 開啟一個 Windows Application 專案,命名為 MdiDemo。
1. 將 Form1 變更檔案名稱為 MainForm,VS 會自動幫你將 class 名稱也一起變更。
2. 在 Design View 可以看到表單的外觀,然後將 MainForm 的 IsMdiContainer 屬性設定為 true。此時會看到表單內區域變成深灰色。
3. 從工具列拉一個 Panel 元件到表單上,並設定 Dock 屬性為 Top。
4. 接下來拉三個 Button 到 Panel 上,分別顯示為 Form1, Form2, Form3
完成以上步驟後,表單外觀如圖(一):
圖(一) MainForm 外觀
接下來,在專案新增三個Form,分別為 ChildForm1, ChildForm2, ChildForm3,並在表單上放一個 Label 元件,如圖(二)。
圖(二) ChildForm 外觀
如此,表單的外觀都完成了,開始在 MainForm 的按鈕事件撰寫呼叫子視窗的程式。
{
ChildForm1 frm = new ChildForm1();
frm.MdiParent = this;
frm.Show();
}
然後在另外兩個按鈕的 Click 事件中,分別呼叫 ChildForm2, ChildForm3。完成後將程式執行,並且按下 button1,結果如圖(三)。
圖(三) 各個 ChildForm 都開在 MainForm 裡面
在 button1_Click 裡面加上一行程式碼。
{
ChildForm1 frm = new ChildForm1();
frm.MdiParent = this;
frm.WindowState = FormWindowState.Maximized; //設定視窗起始狀態為最大化
frm.Show();
}
當按下按鈕後 ChildForm 會自動放到最大,MainForm 會出現一列 MDI 視窗的控制按鈕,如圖(四)。簡單的 MDI 設計模式的便完成了。
圖(四) ChildForm 放到最大的執行結果
二、進階處理
雖然完成了 MDI 模式,但是連續按下 button1 會發現 ChildForm1 可以被重複產生。為修正這個狀況,可以使用 Singleton 設計方式來產生 ChildForm。
首先,手動修改 ChildForm1 的程式碼。
{
#region Singleton
private static ChildForm1 instance = null;
private ChildForm1() //建構子改為 private
{
InitializeComponent();
}
public static ChildForm1 GetInstance()
{
if (instance == null)
{
instance = new ChildForm1();
}
return instance;
}
//關閉視窗後,將instance設為null
private void ChildForm1_FormClosed(object sender, FormClosedEventArgs e)
{
instance = null;
}
#endregion
}
將建構子改為 private 使外部程式不能直接產生物件,必須透過 GetInstance 方法傳回實體。並且在 FormClosed 事件要將 instance 設為 null,否則當關閉 ChildForm1 後再度按下 button1 會發生"Cannot access a disposed object."的錯誤訊息。
三、模擬MDI模式
另外有一種方式可以達到類似 MDI 模式。在專案中新增加一個 MainForm2,但是不用設定 IsMdiContainer 屬性。1. 如同 MainForm 拉一個 Panel 並 Dock 為 Top,然後放三個按鈕上去。
2. 拉一個 Panel 到表單上,命名為 ContainerPanel,Dock 屬性設為 Fill,Padding 屬性四個邊皆設定為 4pixel。
3. 拉一個 Panel 到 ContainerPanel 裡面,命名為 FormPanel,Dock 屬性設為 Fill,BorderStyle 屬性為 Fixed3D,BackColor 為 ControlDark。
完成以上步驟,MainForm2 外觀如圖(五)。
圖(五) MainForm2 外觀
看起來和 MainForm 是不是很像。接著來看 MainForm2 的程式碼。
{
ChildForm1 frm = ChildForm1.GetInstance(); //Singleton方式取得物件實體
OpenForm(frm);
}
private void OpenForm(Form frm)
{
//設定表單屬性
frm.TopLevel = false;
frm.TopMost = false;
frm.FormBorderStyle = FormBorderStyle.None;
frm.WindowState = FormWindowState.Normal;
frm.StartPosition = FormStartPosition.Manual;
frm.Parent = this.FormPanel;
frm.Location = new Point(0, 0);
frm.Size = this.FormPanel.Size;
frm.Dock = DockStyle.Fill;
frm.Visible = true;
frm.BringToFront();
}
button1_click 事件裡面呼叫 ChildForm1.GetInstance() 方法來取得表單實體,然後調用 OpenForm 方法處理顯示表單。重點在於 FormBorderStyle, Parent, Dock 三個屬性的設定,執行起來如圖(六)。
圖(六) MainForm2 執行結果
此種方式,在主視窗上面就不會出現 MDI 視窗的最大化最小化的控制項。(完)
No comments:
Post a Comment