[ASP.NET 自訂控制項]當Label指定的TextBox必KEY時,套用自訂樣式顯示
開發時當網頁很多輸入項,會根據不同條件來設定某些「TextBox」或「其他類型控制項」值是否為必Key。
然而我們通常在input控制項前面,都會放一個Label來代表後面資料輸入項的意義。
例如:
然而根據不同情況,該TextBox可能必KEY,可能非必KEY。
這個時候按照上一篇[ASP.NET 自訂控制項]TextBox動態加入RequiredFieldValidator與CustomValidator的設計,只需修改TextBox.Required屬性。
但是有沒有辦法,讓Lable的「ID」,自己判斷當TextBox的Required為True,把自己改成ID(*)呢?
今天要分享的,就是怎麼設計一個Label,當他指定的控制項(這裡例子是TextBox)為必KEY時,
將Label.Text自動套用到設定的樣式裡。
Download Source Code: LabelRequiredFormat.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>。
Step6:
高興的話,可以在WebConfig加上整個專案的RequiredFormat。這邊的設定是加上(*),只有*是藍色的。
<appSettings>
<add key="LabelReqriedFormat" value="{0}(<font color="blue">*</font>)"/>
</appSettings>
Step6:
大功告成,只需要建置一下Joey類別庫,產生Joey.dll,在專案加入參考後,就有個JoeyLabel可以使用。
我們來看一下畫面。
這邊是Label沒有設定RequiredFormat,WebConfig設定成上述的範例,TextBox的Required設成True時,
ID後面加上了(*),且*為藍色。
按下「把TextBox變成非必KEY」按鈕後,將TextBox.Required設成false。
再按下「把TextBox變成必KEY」按鈕後,就會恢復成一樣的畫面。
接著我們把Lable.RequiredFormat改一下,改成{0}-<font color="red">不能為空</font>
當什麼都沒有設定時,會讀取Resources.Message.resx裡面的<font color="red">(*)</font>。
這邊感謝jeff大大分享的遞迴findcontrol方法。
blog 與課程更新內容,請前往新站位置:http://tdd.best/