.net開發筆記(十一) 設計時(Design-Time)和運行時(Run-Time)的區別

來源:互聯網
上載者:User

    設計時和運行時的概念網上的中文資料很少,如果不是做第三方組件開發的或者跟設計器開發有關的,幾乎用不到這些概念。為了迎合之前幾篇部落格,我想有必要說一下它兩的概念和區別,以及用在什麼地方。部落格好久沒更新,比較忙。

    首先,我個人認為“設計時”和“運行時”是針對組件而言的(包括控制項),也就是說,一個組件可以處在“運行時”也可以處在“設計時”兩個狀態,從字面上的意思來看,“設計時”當然是指處在開發階段,開發人員在設計器中開發組件的時候,而“運行時”指程式處在運行階段,比如一個button控制項,在設計器中的表單中時,它就處於“設計時”,當程式運行起來之後,這個button還是在表單中,但它處於“運行時”了。呵,字面上的意思很好理解,那麼這兩個狀態到底有什麼用呢?也就是說,微軟為什麼規定組件有兩個狀態?想要瞭解這個問題的答案,我們先得清楚“視覺化設計工具”(比如VS  IDE)的作用,簡單的總結一下:視覺化設計工具提供一個WYSIWYG(所見即所得 (WYSIWYG))的開發環境,為開發人員提供一個更直觀的操作平台。可是,就是這麼兩句簡單的話,卻迷惑了多少人。我們來看一張圖:

,任何組件都是可以放在“設計器”中設計的(詳見前面幾篇部落格),也就是說,組件具備“可視化設計”的特性,開發人員通過向設計器中添加組件,就可以快速地設計出一個類型(Form1),然後產生代碼文檔,儲存。整個過程需要注意一下幾點:

1)  組件具備“可視化設計”的特性,這裡的設計並不代表我們可以改變原有組件的代碼,比如向設計器中拖進一個Button控制項,預設命名“button1”,接著我們編輯它的屬性、綁定事件等等,這些所有的操作都只發生在button1身上,並不會影響原來Button類代碼。換句話說,只設計“組件執行個體“。

2)  開發人員向設計器中添加組件(包括控制項),設計器中的組件都是“執行個體”,也就是說圖中的label1、textbox1、button1這些東西都是實實在在地“控制項執行個體”,什麼叫“控制項執行個體”?就是說它們都有自己的控制代碼(Handle)、視窗過程(WndProc)(控制項即表單,表單即控制項,表單都有控制代碼和視窗過程,不清楚的請看前面的部落格),如果諸位不相信,可以用Spy++查看設計器中的這些控制項,可以尋找出它們的Handle以及其他資訊。關於這一點,我前面部落格已經解釋過,這裡我再提一下。

3)  不管我們怎麼操作設計器,我們在設計器中看到的東西確實跟程式運行後的介面大概差不多,但是需要明白的是,設計器中的東西全部都是“虛”的,為什麼說它是虛的?因為我們一關閉設計器之後,設計器中的東西全部銷毀了,而真正有用的東西就是圖中③產生的程式碼文檔!對,你沒有看錯,我更沒有寫錯,代碼文檔才是我們最終需要的東西,我們可以將它編譯產生exe或者dll檔案,不是嗎?

4)  接3),我們可以一句話來概括一下“設計器”的作用:為了更快的產生想要的代碼。是的,設計器最終的目的就是為開發人員快速產生代碼,換句話說,假如沒有設計器,開發人員完全可以自己去寫代碼(比中的Form1.cs和Form1.Designer.cs),可是沒有哪個sb會這樣去做,因為那樣實在太麻煩了。

5)  我們將產生的程式碼文檔編譯產生exe檔案,運行之,我們會看見什嗎?毫無疑問,我們會看見與設計器中差不多類似的介面,有一個label、一個textbox、一個button。這個是為什嗎?因為產生的程式碼都是由設計器產生的,我們拖進去一個Label,設計器就會產生類似如下的代碼:

Label  label1 = new Label();

label1.Location = new Point(10,10);

label1.Text = “label1”;

this.Controls.Add(label1);

//大概類似這樣,可能不相同

同理,textbox1和button1也一樣。如果我們在屬性列表中修改label1的Text屬性為“test”,那麼,立即有這樣的代碼產生:

label1.Text = “test”;

注意,以上自動產生的程式碼都在InitializeComponent方法中,我們將產生的程式碼編譯運行,當然會按照原來設計時的樣子一一還原。

     如果看懂以上5點的童鞋,那麼基本上就能理解本篇部落格所要說明的問題了。我們再來回憶一下文章開始提出來的問題:組件為啥要有兩個狀態,設計時(Design-Time)和運行時(Run-Time)?答案在2)和5)中,已經說過,設計器中的任何組件都是執行個體,換句話說,你往設計器中拖放組件的時候,會調用它的構造方法,如果該組件恰好是一個控制項,那麼肯定會激發它的Load事件,當它在設計器中重繪時,肯定會激發它的Paint事件等等等。也就是說,如果我自訂一個控制項:

1 MyControl:UserControl2 {3 protected override OnLoad(EventArgs e)4 {5      MessageBox(“載入了!”);6 }7 }

View Code

本來設計這個自訂控制項的開發人員想讓控制項載入時,彈出一個訊息框,現在問題來了,使用這個自訂控制項的coder,只要將該控制項拖進設計器時,就會彈出一個MessageBox,毫無疑問,這不是我們希望的。如:

這隻是一個簡單例子,如果我們在開發第三方組建時,需要在某些場合進行IO操作、訪問資料庫或者操作註冊表等等,那麼就有必要考慮這些會不會在設計器中發生,比如修改一下上面的代碼:

1 MyControl:UserControl2 {3 protected override OnLoad(EventArgs e)4 {5      //操作註冊表6      //串連資料庫7 }8 }

View Code

問題就顯而易見了,只要你將該控制項拖進設計器,那麼就會發生“操作註冊表”或者“串連資料庫”這樣的行為。

     想要解決以上問題,微軟就提出來了“設計時”和“運行時”的概念,其實就我個人理解,同一個組件,它出現在設計器中,它就是處於“設計時”,否則它就是處於“運行時”,每個組件都有一個DesinMode屬性,如果該屬性為true,那麼它就是處於“設計時”,否則,它就是處於“運行時”。(註:該方法判斷不太準確,只適合大部分場合,使用所有場合的判斷方法現在不必提及)

那麼,原有代碼就可以修改為:

 1 MyControl:UserControl 2 { 3 protected override OnLoad(EventArgs e) 4 { 5 if(!DesignMode)  //如果不處於“設計時” 6 { 7        //操作註冊表 8        //串連資料庫 9     }10 }11 }

View Code

    問題完美解決。設計時和運行時的概念,就像同一個人,出生在官宦之家,那麼他就是“官二代”,如果出生在普通家庭,那麼他很有可能是所謂的“屌絲”。官二代和屌絲有很大的區別,就像設計器中的Button和運行期間的Button,差別很大。

    另外,至於為什麼設計器中的組件與運行時的組件能有不同的表現,比如設計器中的組件可以通過屬性列表編輯它的屬性,可以改變它的位置、大小等等等等,甚至為什麼會自動產生代碼,這些東西都屬於設計器所必須具備的功能,本篇文章不討論。

代碼為word中所寫,如有錯誤,望見諒!希望對諸位有協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.