2008/01/02

Visual Studio 2008 Express 免費下載

軟體開發人員眾所矚目的 Visual Studio 2008 RTM 公布了,連同 Express 版本也開放下載。喜歡搶鮮的朋友可以去 Express 開發者網站下載。更重要的是,下載後要去註冊,可以獲得許多 3rd party 的元件。包含:

  • Rad ribbonbar by Telerik — Provides an easy-to-design implementation of Microsoft Office 2007 ribbon user interface.
  • BubbleBar by DevComponents — A uniquely tabbed toolbar control with magnifying/bubbling buttons.
  • SpreadsheetGear for .NET by SpreadsheetGear — Develop Microsoft Excel compatible Windows Forms and ASP.NET Microsoft Reporting applications.

看到這些有沒有已經流口水了。

Windwos Form 開發 : MDI 設計模式 step by step

使用 .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
完成以上步驟後,表單外觀如圖(一):

Figure1
圖(一) MainForm 外觀

接下來,在專案新增三個Form,分別為 ChildForm1, ChildForm2, ChildForm3,並在表單上放一個 Label 元件,如圖(二)。

Figure2
圖(二) ChildForm 外觀

如此,表單的外觀都完成了,開始在 MainForm 的按鈕事件撰寫呼叫子視窗的程式。

private void button1_Click(object sender, EventArgs e)
{
ChildForm1 frm = new ChildForm1();
frm.MdiParent = this;
frm.Show();
}

然後在另外兩個按鈕的 Click 事件中,分別呼叫 ChildForm2, ChildForm3。完成後將程式執行,並且按下 button1,結果如圖(三)。

Figure3
圖(三) 各個 ChildForm 都開在 MainForm 裡面

在 button1_Click 裡面加上一行程式碼。

private void button1_Click(object sender, EventArgs e)
{
ChildForm1 frm = new ChildForm1();
frm.MdiParent = this;
frm.WindowState = FormWindowState.Maximized; //設定視窗起始狀態為最大化
frm.Show();
}

當按下按鈕後 ChildForm 會自動放到最大,MainForm 會出現一列 MDI 視窗的控制按鈕,如圖(四)。簡單的 MDI 設計模式的便完成了。

Figure4
圖(四) ChildForm 放到最大的執行結果

二、進階處理

雖然完成了 MDI 模式,但是連續按下 button1 會發現 ChildForm1 可以被重複產生。為修正這個狀況,可以使用 Singleton 設計方式來產生 ChildForm。
首先,手動修改 ChildForm1 的程式碼。

public partial class ChildForm1 : Form
{
#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 外觀如圖(五)。

Figure5
圖(五) MainForm2 外觀

看起來和 MainForm 是不是很像。接著來看 MainForm2 的程式碼。

private void button1_Click(object sender, EventArgs e)
{
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 三個屬性的設定,執行起來如圖(六)。

Figure6
圖(六) MainForm2 執行結果

此種方式,在主視窗上面就不會出現 MDI 視窗的最大化最小化的控制項。(完)

Book: Framework Design Guidelines

之前看了一篇MSDN雜誌的關於LINQ發展的文章,文章說明了LINQ語法的緣由,特別是語法背面的物件技術背景。文中提到 "理想語法" 的概念,描述一個理想的資料存取語法,然後說明其中的物件技術背景,再而衍生出lambda 運算式。最後為了讓熟悉SQL語法的開發者能夠銜接,於是逐步發展成理想的LINQ語法。原文連結入下:MSDN Magazine, June 2007: LINQ 的發展及其對 C# 設計的影響

Framework_Design_Guidelines_cover最近在看 "Framework Design Guidelines" 一書,作者是參與開發 .NET Framework 的核心人員,書中說明許多 framework 的開發指引,有許多非常實用的建議。在此書第二章說明了開發 API 重要的原則: 場景驅動設計 (scenario driven design)。以使用者的角度,先編寫一些對主要使用場景來說不可少的程式碼,然後再設計物件模型來支援這些範例程式碼。

這裡所謂 "範例程式碼" 就是 "理想語法"。此書中定義的開發規範涵蓋 .NET Framework 2.0,而Anders Hejlsberg (C#與Delphi之父) 說這些規範還在指導著微軟下一代 API (WinFX (現在正式稱做 .NET Framework 3.0) ) 的開發。前後觀之,在 .NET Framework 3.5 都依循這樣的開發原則進行著。

這本書不論是對發展 API 有所幫助,對於程式開發也可獲得許多有價值的建議,值得推薦給所有的程式開發者。