推薦文章html
原文做者 :伍華聰數據庫
原文地址 :http://www.cnblogs.com/wuhuacong/p/3508467.html設計模式
在開發Winform程序的時候,咱們每每須要根據須要作一些自定義的控件模塊,這樣能夠給系統模塊重複利用,或者實現更好的效果等功能。但在使用的時候,咱們又每每設計時刻發現一些莫名其妙的錯誤,那麼咱們該如何進行控件的設計時刻的開發調試呢,如何解決碰到設計時刻出現的錯誤呢?本文主要介紹我本身在這方面積累的一些經驗和處理方法,指望對你們有幫助。工具
例如個人通用附件模塊裏面,有一個自定義控件,須要提供給外部使用的,以下所示。測試
這裏外部使用的模塊,是工做流裏面的一個模塊,也是一個自定義控件,我想把它做爲一個流程信息的展現控件。this
所以就想把這個附件管理的自定義控件拖動到另一個自定義控件流程信息展現控件裏面,設計的流程信息管理的界面以下所示,這個時候,使用這個附近控件是沒有問題的,正常拖動到另一個控件裏面。spa
編譯整個項目,左邊的VS工具箱會出現一個ApplyControl的自定義控件,可是當我拖動該控件到新的窗體界面裏面的時候,錯誤就出現了。設計
這個問題多是由於調用了訪問數據庫的操做,可是更加詳細的位置咱們看不太清楚(數據給截斷顯示了)。3d
爲了更好跟蹤到錯誤的發生的地方,咱們能夠用VS自帶的調試操做來進行跟蹤。調試
首先咱們在項目的【屬性】-》【調試】裏面設置啓動操做爲指定的VS,選擇「啓動外部程序」爲對應版本的VS的IDE程序,以下所示。
啓動調試後,打開對應的這個項目,而後再次模擬從工具箱裏面拖動控件的效果,這樣VS IDE就能定位到具體的位置了。
咱們發現VS定位到一個綁定數據的數據庫訪問操做裏面去,可是我開始一直不明白,這個BindData的操做,其實已是經過指定了設計時刻不進行的了(!this.DesignMode),不知道爲何還繼續。
public void BindData() { ClearData(); if (!this.DesignMode) { List<FileUploadInfo> fileList = new List<FileUploadInfo>(); if (!string.IsNullOrEmpty(this.AttachmentGUID)) { fileList = BLLFactory<FileUpload>.Instance.GetByAttachGUID(this.AttachmentGUID, this.pager1.PagerInfo); } else { fileList = BLLFactory<FileUpload>.Instance.GetAllByUser(this.UserId, this.AttachmentDirectory, this.pager1.PagerInfo); } ..........................
調試到這個DesignMode的時候,它的值居然是false,那麼確定就會去從數據庫獲取了,而設計時候去找數據,這個時候就出錯了。至於爲何會是DesignMode爲false,開始有點搞不太清楚,不是說好設計時刻爲True的嗎?
經過搜索,發現有爲仁兄總結的比較精闢,這裏就借用一下。
「也就是說一個控件只有在它本身被拖拽到設計器的時候,其 DesignMode 纔是真,若是它被包含在其餘控件中被加入到設計器,那麼那個控件纔是在設計模式,而它不是!換句話說,DesignMode 並不能反映當前環境是不是運行時,它只能告訴你,這個控件當前是否是直接被設計器操做(嵌套的已經不算了) 。」
那解決方法應該如何呢,其實也很簡單,就是重寫下這個DesignMode的屬性爲咱們指望的值便可,以下所示。
/// <summary> /// 標題:獲取一個值,用以指示 System.ComponentModel.Component 當前是否處於設計模式。 /// 描述:DesignMode 在 Visual Studio 產品中存在 Bug ,使用下面的方式能夠解決這個問題。/// </summary> protected new bool DesignMode { get { bool returnFlag = false; #if DEBUG if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime) { returnFlag = true; } else if (System.Diagnostics.Process.GetCurrentProcess().ProcessName.ToUpper().Equals("DEVENV")) { returnFlag = true; } #endif return returnFlag; } }
從新編譯控件,而後測試拖動,操做正常,再無出錯,搞定!