[ASP.NET]UserControl透過屬性,動態加入RequiredFieldValidator

  • 9481
  • 0
  • 2009-12-25

[ASP.NET]UserControl透過屬性,動態加入RequiredFieldValidator

前言

原理同之前設計在Custom Control裡面一樣,請參考:TextBox動態加入RequiredFieldValidator與CustomValidator

只是這邊是運用在User Control裡面,因為User Control組合的彈性更大,
順手寫個範例給開發的team member作個參考,也希望各位前輩不吝賜教。
 

介紹

這邊的User Control仍為之前範例上,有兩個TextBox,一個為ID,一個為Name。

需求:

  1. 要有property可以存取CodeID與CodeName的值
  2. 要有property可以控制CodeID與CodeName是否為必要輸入項
  3. 要能與外界ValidationGroup一起運作
  4. 錯誤訊息要能讀取Resource檔,且與外界互動(例如:XXX 代碼 不可空白,XXX要能給外面設定)
  5. 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則是長這樣:

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);
        }
    }


最後來看看結果:

message

 

結論

這個範例可以練習到

  1. User Control屬性的開立
  2. ViewState的應用
  3. 動態加入驗證控制項
  4. 讀取訊息檔方法的共用
  5. 讓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/