[ASP.NET 自訂控制項]當Label指定的TextBox必KEY時,套用自訂樣式顯示

  • 6623
  • 0

[ASP.NET 自訂控制項]當Label指定的TextBox必KEY時,套用自訂樣式顯示

開發時當網頁很多輸入項,會根據不同條件來設定某些「TextBox」或「其他類型控制項」值是否為必Key。

然而我們通常在input控制項前面,都會放一個Label來代表後面資料輸入項的意義。

例如:

label與textbox

然而根據不同情況,該TextBox可能必KEY,可能非必KEY。

這個時候按照上一篇[ASP.NET 自訂控制項]TextBox動態加入RequiredFieldValidator與CustomValidator的設計,只需修改TextBox.Required屬性。

但是有沒有辦法,讓Lable的「ID」,自己判斷當TextBox的Required為True,把自己改成ID(*)呢?

 

今天要分享的,就是怎麼設計一個Label,當他指定的控制項(這裡例子是TextBox)為必KEY時,

將Label.Text自動套用到設定的樣式裡。


Download Source CodeLabelRequiredFormat.rar


Step1:

一樣建立Joey類別庫,新增一個類別叫做JoeyLabel.cs。這邊我們把System.Configuration匯入,因為通常樣式這種東西整個專案都會一致。

我們設計上讓專案管理人員,可自行在webconfig設定RequiredFormat。

繼承Label的類別,並宣告兩個string的全域變數,_objID為預指定之控制項ID。_strRequiredFormat則是RequiredFormat。

接著自訂CheckRequiredID與RequiredFormat兩個屬性,供開發人員使用。

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
namespace Joey
{
    public class JoeyLabel: Label
    {

        private string _objID=string.Empty;
        private string _strRequiredFormat = string.Empty;
    }
}

 

        #region Property

        /// <summary>
        /// Gets or sets the Control's ID when required .
        /// </summary>
        /// <value>The check required ID.</value>
        public string CheckRequiredID
        {
            get { return _objID; }
            set { _objID = value; }
        }

        /// <summary>
        /// Gets or sets the required format.
        /// </summary>
        /// <value>The required format.</value>
        /// <remarks>格式{0}為Label.Text,可使用html語法</remarks>
        public string RequiredFormat
        {
            get { return _strRequiredFormat; }
            set { _strRequiredFormat = value; }
        }

        #endregion

 

Step2:

我們需要一個function叫做FindControlExist(),使用遞迴的方式,可以用來找到頁面上指定ID的Control,

這邊可以參考「ASP.NET 魔法學院」jeff大大的遞迴方式的 FindControl

        /// <summary>
        /// Finds the control exist.
        /// </summary>
        /// <param name="Parent">The parent.</param>
        /// <param name="ID">The ID.</param>
        /// <returns>請參考「ASP.NET 魔法學院」大大的文章</returns>
        private Control FindControlExist(System.Web.UI.Control Parent, string ID)
        {
            Control oCtrl = null;            

            //先使用 FindControl 去尋找指定的子控制項
            oCtrl = Parent.FindControl(ID);

            //若尋找不到則往下層遞迴方式去尋找()
            if (oCtrl == null)
            {
                foreach (Control oChildCtrl in Parent.Controls)
                {
                    //以遞迴方式呼叫原函式
                    oCtrl = FindControlExist(oChildCtrl, ID);
                    //若有尋找到指定控制項則離開迴圈
                    if (oCtrl != null) break; 

                }
            }
            return oCtrl;
        }

 

Step3:

 

 

 

 

接著就是精髓所在了,設計一個function叫做GetRenderContent(),回傳值為套好樣式後要使用的字串。

當Label.RequiredFormat有設定時,以Label的設定為主。

當Label.RequiredFormat沒設定時,以WebConfig的LabelReqriedFormat的設定為主。

當LabelReqriedFormat也沒有設定時,則以Joey.Resource裡面,預設樣式Message.LabelRequiredFormat為主。

        /// <summary>
        /// Gets the content of the render.
        /// </summary>
        /// <returns></returns>
        private string GetRenderContent()
        {
            Control ctrlObject = FindControlExist(this.Page, this.CheckRequiredID);
             
            if (ctrlObject != null)
            {
                if (typeof(Joey.JoeyTextBox).IsInstanceOfType(ctrlObject))
                {
                    if ((((JoeyTextBox)ctrlObject)).Required)
                    {
                        if (this.RequiredFormat.Trim().Length == 0)
                        {
                            string strConfigRequiredFormat = string.Empty;
                            //當是run time的時候,若RequiredFormat屬性沒設定,則以web config設定為主。
                            //當web config也沒設定時,以Resource.Message.LabelRequiredFormat預設樣式呈現。
                            if (System.Web.HttpContext.Current != null)
                            {
                                if (ConfigurationManager.AppSettings["LabelReqriedFormat"]!=null)
                                { strConfigRequiredFormat = ConfigurationManager.AppSettings["LabelReqriedFormat"].ToString(); }                                
                            }

                            if (strConfigRequiredFormat.Trim().Length == 0)
                            {
                                return string.Format(Resources.Message.LabelRequiredFormat, this.Text);
                            }
                            else 
                            {
                                return string.Format(strConfigRequiredFormat, this.Text);
                            }
                            
                        }
                        else
                        { return string.Format(RequiredFormat, this.Text); }                        
                    }                    
                }
            }
            return this.Text;
        }

 

Step4:

有了套用樣式的字串後,我們只需把他Render到頁面上即可。

Step3跟Step4,為什麼不直接把值套入Label.Text就好呢?

因為我們不希望樣式去影響到原本Label.Text的值,假如網頁程式裡有判斷到該Label.Text,就會造成誤判。

另外一點Label.Text=String.Format({0}*,Label.Text)的方式,會造成每次Render都會累加星號*,星號*會越來越多。

        #region Override Method

        /// <summary>
        /// 將控制項呈現在指定的 HTML 寫入器中。當指定檢查的控制項Required為True時,套上RequiredFormat。
        /// </summary>
        /// <param name="writer">接收控制項內容的 <see cref="T:System.Web.UI.HtmlTextWriter"/> 物件。</param>
        protected override void Render(HtmlTextWriter writer)
        {
            //base.Render(writer);
            string strOutPutText = GetRenderContent();
            AddAttributesToRender(writer);
            writer.RenderBeginTag(HtmlTextWriterTag.Label);
            writer.Write(strOutPutText);
            writer.RenderEndTag();
        }
        #endregion

 

Step5:

 

我們在Resources.Message.resx裡,加上預設的RequiredFormat。這邊是希望必KEY時加上(*),且顏色為紅色。

所以Value為{0}<font color="red">(*)</font>。

resourceFormat

 

Step6:

高興的話,可以在WebConfig加上整個專案的RequiredFormat。這邊的設定是加上(*),只有*是藍色的。

  <appSettings>
    <add key="LabelReqriedFormat" value="{0}(&lt;font color=&quot;blue&quot;&gt;*&lt;/font&gt;)"/>
  </appSettings>

Step6:

 

大功告成,只需要建置一下Joey類別庫,產生Joey.dll,在專案加入參考後,就有個JoeyLabel可以使用。

我們來看一下畫面。

這邊是Label沒有設定RequiredFormat,WebConfig設定成上述的範例,TextBox的Required設成True時,

ID後面加上了(*),且*為藍色。

原畫面

按下「把TextBox變成非必KEY」按鈕後,將TextBox.Required設成false。

按下非必KEY按鈕

 

再按下「把TextBox變成必KEY」按鈕後,就會恢復成一樣的畫面。

原畫面

 

接著我們把Lable.RequiredFormat改一下,改成{0}-<font color="red">不能為空</font>

自訂樣式

當什麼都沒有設定時,會讀取Resources.Message.resx裡面的<font color="red">(*)</font>。

讀resource裡的樣式

 

 

 

這邊感謝jeff大大分享的遞迴findcontrol方法。


或許您會對下列培訓課程感興趣:

  1. 2021/1/9:【針對遺留代碼加入單元測試的藝術】202101 - 台北
  2. 2021/1/10:【極速開發+】 202101 台北
  3. 2021/2/20~2021/2/21:【演化式設計】測試驅動開發與持續重構 202102

想收到第一手公開培訓課程資訊,或想詢問企業內訓、顧問、教練、諮詢服務的,請洽 Facebook 粉絲專頁:91敏捷開發之路