[ASP.NET]UserControl透過屬性,動態加入RequiredFieldValidator
前言
原理同之前設計在Custom Control裡面一樣,請參考:TextBox動態加入RequiredFieldValidator與CustomValidator
只是這邊是運用在User Control裡面,因為User Control組合的彈性更大,
順手寫個範例給開發的team member作個參考,也希望各位前輩不吝賜教。
介紹
這邊的User Control仍為之前範例上,有兩個TextBox,一個為ID,一個為Name。
需求:
- 要有property可以存取CodeID與CodeName的值
- 要有property可以控制CodeID與CodeName是否為必要輸入項
- 要能與外界ValidationGroup一起運作
- 錯誤訊息要能讀取Resource檔,且與外界互動(例如:XXX 代碼 不可空白,XXX要能給外面設定)
- PostBack與多個User Control要能正常運作
接著讓我們看下去…
Play it
aspx上,要有兩個TextBox,分別為txtID與txtName。
<asp:TextBox ID="txtID" runat="server"></asp:TextBox>
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
針對第一個需求與第二個需求,我們開四個屬性出來,
特別要注意的是,Required的屬性要使用ViewState記,不然PostBack會掉。
/// Gets or sets the code ID.
/// </summary>
/// <value>The code ID.</value>
public string CodeID {
get { return this.txtID.Text; }
set { this.txtID.Text = value; }
}
/// <summary>
/// Gets or sets a value indicating whether [code ID required].
/// </summary>
/// <value><c>true</c> if [code ID required]; otherwise, <c>false</c>.</value>
public bool CodeIDRequired {
get {
return (bool)(this.ViewState["CodeIDRequired"]??false);
}
set { this.ViewState["CodeIDRequired"] = value; }
}
/// <summary>
/// Gets or sets the name of the code.
/// </summary>
/// <value>The name of the code.</value>
public string CodeName
{
get { return this.txtName.Text; }
set { this.txtName.Text = value; }
}
/// <summary>
/// Gets or sets a value indicating whether [code name required].
/// </summary>
/// <value><c>true</c> if [code name required]; otherwise, <c>false</c>.</value>
public bool CodeNameRequired {
get { return (bool)(this.ViewState["CodeNameRequired"]??false); }
set { this.ViewState["CodeNameRequired"] = value; }
}
根據第三個需求與第四個需求,我們要開ValidationGroup的屬性與一個供外界設定錯誤訊息的屬性。
/// Gets or sets the mapping label text.
/// </summary>
/// <value>The mapping label.</value>
public string MappingLabel { get; set; }
/// <summary>
/// Gets or sets the validation group.
/// </summary>
/// <value>The validation group.</value>
public string ValidationGroup
{
get { return this.txtID.ValidationGroup; }
set {
this.txtID.ValidationGroup = value;
this.txtName.ValidationGroup = value;
}
}
要讀取Resource檔的訊息代碼,我這邊寫在BasePage,並且宣告成static。
{
public BasePage()
{
//
// TODO: 在此加入建構函式的程式碼
//
}
/// <summary>
/// Getmessages the specified Message id.
/// </summary>
/// <param name="MsgId">The Message id.</param>
/// <returns></returns>
public static string GetMessage(string MsgId)
{
return Resources.Message.ResourceManager.GetString(MsgId);
}
}
Message則是長這樣:
最後,
我們要在User Control的Page_PreRender事件,判斷Required屬性,是否為True,再決定是否要動態加入RequiredFieldValidator。
{
if (this.CodeIDRequired)
{
RequiredFieldValidator codeIDRequiredValidator = new RequiredFieldValidator();
codeIDRequiredValidator.Display = ValidatorDisplay.None;
codeIDRequiredValidator.ValidationGroup = this.ValidationGroup;
codeIDRequiredValidator.ControlToValidate = this.txtID.ID;
//這邊是結合Resource的Message檔,搭配string.Format,可以結合更多的應用
//在這裡,10400代表『欄位不可空白』
codeIDRequiredValidator.ErrorMessage = string.Format(BasePage.GetMessage("10400"), MappingLabel + "代碼");
this.Controls.Add(codeIDRequiredValidator);
}
if (this.CodeNameRequired)
{
RequiredFieldValidator codeNameRequiredValidator = new RequiredFieldValidator();
codeNameRequiredValidator.Display = ValidatorDisplay.None;
codeNameRequiredValidator.ValidationGroup = this.ValidationGroup;
codeNameRequiredValidator.ControlToValidate = this.txtName.ID;
//這邊是結合Resource的Message檔,搭配string.Format,可以結合更多的應用
//在這裡,10400代表『欄位不可空白』
codeNameRequiredValidator.ErrorMessage = string.Format(BasePage.GetMessage("10400"), MappingLabel+"姓名");
this.Controls.Add(codeNameRequiredValidator);
}
}
最後來看看結果:
結論
這個範例可以練習到
- User Control屬性的開立
- ViewState的應用
- 動態加入驗證控制項
- 讀取訊息檔方法的共用
- 讓User Control的驗證訊息可以讀訊息檔,也可以跟外界互動
最後成功的把Required,封裝在User Control裡面,讓使用的人只需要設定一個屬性就可以搞定。
把相關檔案Sample Code附上來,可以玩玩看測試的頁面,有問題歡迎反應給我,謝謝。
Sample Code:UserControlRequired.zip
[註1]:2009/12/24,屬性若使用ViewState,請自行判斷是否為null,若是,則給預設值(例如false或string.empty),
否則可能出現Null exception。已將判斷補上文章上sample code
blog 與課程更新內容,請前往新站位置:http://tdd.best/