自定義控件開發的調試及DesignMode的狀態處理


在開發Winform程序的時候,我們往往需要根據需要做一些自定義的控件模塊,這樣可以給系統模塊重復利用,或者實現更好的效果等功能。但在使用的時候,我們又往往設計時刻發現一些莫名其妙的錯誤,那么我們該如何進行控件的設計時刻的開發調試呢,如何解決碰到設計時刻出現的錯誤呢?本文主要介紹我自己在這方面積累的一些經驗和處理方法,期望對大家有幫助。

1、自定義控件的設計錯誤產生

例如我的通用附件模塊里面,有一個自定義控件,需要提供給外部使用的,如下所示。

這里外部使用的模塊,是工作流里面的一個模塊,也是一個自定義控件,我想把它作為一個流程信息的展示控件。

因此就想把這個附件管理的自定義控件拖動到另外一個自定義控件流程信息展示控件里面,設計的流程信息管理的界面如下所示,這個時候,使用這個附近控件是沒有問題的,正常拖動到另外一個控件里面。

編譯整個項目,左邊的VS工具箱會出現一個ApplyControl的自定義控件,但是當我拖動該控件到新的窗體界面里面的時候,錯誤就出現了。

 

這個問題可能是因為調用了訪問數據庫的操作,但是更加詳細的位置我們看不太清楚(數據給截斷顯示了)。

2、基於Visual Studio控件的調試

為了更好跟蹤到錯誤的發生的地方,我們可以用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);
                }

                ..........................

3、DesignMode的重載,問題解決

調試到這個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;
    }
}

重新編譯控件,然后測試拖動,操作正常,再無出錯,搞定!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM