在製作控制項的時候容易遇到「呈現控制項時出錯」「發生了未處理的異常。未將物件參考設定到物件的實例。」這樣的錯誤,如下圖:(也有可能僅僅只是因為未設定runat ="server"標籤而導致該錯誤,請先檢查該項目。
如圖所示的情況我們稱之為「設計時」以區別於「編譯時」/「運行時」。
讓我們分析控制在設計時的表現,我們的控制在設計時的時候,VS智能地模擬輸出控制在運行時的樣貌,控制的呈現通過了一定順序的方法,並最終形成了當前輸出。依照標準,我們應該是在Render或RenderContents中對控制進行了輸出的操作(事實上其他也是可以,但我們通常也不那麼做,或者說更多的「呈現控制時出錯」的異常主要來自於Render或RenderContents)。
從錯誤的提示「未將物件參考設定到物件的實例。」從這句話來看,也就是說,有一個或以上的物件的實例在沒有賦初值的情況下就被使用了。
protected override void RenderContents(HtmlTextWriter writer) { UpButton.Text = Page.Server.HtmlDecode(UpButton.Text); DownButton.Text = Page.Server.HtmlDecode(DownButton.Text); base.RenderContents(writer); }因為該控制項在設計的時候需要有一個向上的按鈕和一個向下的按鈕,分別需要用兩個特殊的標點符號向上和向下,而這兩個符號需要透過設定如下所示的程式碼編號才可以正確地被瀏覽器呈現:
private string upButtonText = "∧"; private string downButtonText = "∨";而這兩個符號在呈現前卻會被頁面進行一個HtmlEncode方法編譯後再輸出,而這兩個特殊的標誌卻只能透過直接輸出的方式來呈現,也就是說在HtmlEncode之後只能將該特殊標誌以文字的形式輸出∧ ∨而不會輸出向上和向下的箭頭。這時候我們需要引入它的反向方法Page.Server.HtmlDecode進行解碼,注意到這裡我們使用了Page實例,該實例只有在頁面真實存在的情況下才為非空,否則後續的操作將是對null的操作,而這樣的操作將會顯示「未將物件引用設定到物件的實例。」這樣的錯誤。
設計時:我們剛才提到了,設計時只是模擬頁面呈現的過程,而頁面事實上是不存在的。因此在這個時候Page物件的實例將為空,後續的呼叫將引發異常。
protected override void RenderContents(HtmlTextWriter writer) { if (!DesignMode) { UpButton.Text = Page.Server.HtmlDecode(UpButton.Text); DownButton.Text = Page.Server.HtmlDecode(DownButton.Text); } base.RenderContents(writer); }這樣只有在非設計時的時候,我們才引入Page物件的實例,因此設計時的異常將迎刃而解。 總結