Here’s the code for the control, (just to make sure there are no unknown
differences):
using
System;
using System.Text;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.Security.Permissions;
namespace Controls.TextBoxes {
///
<summary>
/// Summary description for PhoneControl
///
</summary>
[AspNetHostingPermission(SecurityAction.LinkDemand,
Level =
AspNetHostingPermissionLevel.Minimal),
DefaultProperty("Text"),
ToolboxData("<{0}:PhoneNumberTextCtrl runat=\"server\">
</{0}:PhoneNumberTextCtrl>")]
public
class
PhoneNumberTextCtrl : CompositeControl
{
private TextBox
phoneTextBox;
private
RequiredFieldValidator phoneRequired;
private
RegularExpressionValidator phoneRegex;
private Style
phoneStyle;
#region Properties
[Bindable(true),
Category("Appearance"),
Description("Phone
number for textbox")]
public string
Text {
get {
return (string)ViewState["Text"]
?? String.Empty;
}
set {
ViewState["Text"] =
value;
}
}
[Bindable(true),
Category("Behavior"),
Description("Is
this field Required?")]
public bool
Required {
get {
return (bool?)ViewState["Required"]
?? false;
}
set {
ViewState["Required"] =
value;
}
}
[Bindable(true),
Category("Behavior"),
Description("Error
Message to display if textbox is left blank")]
public string
RequiredErrorMessage {
get {
return (string)ViewState["RequiredErrorMessage"]
?? String.Empty;
}
set {
ViewState["RequiredErrorMessage"] =
value;
}
}
[Bindable(true),
Category("Behavior"),
Description("Error
Message to display if textbox is left blank")]
public string
RequiredErrorText {
get {
return (string)ViewState["RequiredErrorText"]
?? String.Empty;
}
set {
ViewState["RequiredErrorText"] =
value;
}
}
[Bindable(true),
Category("Behavior"),
Description("Validation
Group the control belongs to")]
public string
ValidationGroup {
get {
return (string)ViewState["ValidationGroup"]
?? String.Empty;
}
set {
ViewState["ValidationGroup"] =
value;
}
}
[Bindable(true),
Category("Behavior"),
Description("Is
this field Required?")]
public bool
FormatRequired {
get {
return (bool?)ViewState["FormatRequired"]
?? (false);
}
set {
ViewState["FormatRequired"] =
value;
}
}
[Bindable(true),
Category("Behavior"),
Description("Text
to display if the phone number is not in the correct format")]
public string
FormatErrorMessage {
get {
return (string)ViewState["FormatErrorMessage"]
?? String.Empty;
}
set {
ViewState["FormatErrorMessage"] =
value;
}
}
[Bindable(true),
Category("Behavior"),
Description("Text
to display if the phone number is not in the correct format")]
public string
FormatErrorText {
get {
return (string)ViewState["FormatErrorText"]
?? String.Empty;
}
set {
ViewState["FormatErrorText"] =
value;
}
}
[Bindable(true),
Category("Behavior"),
Description("Regular
expression used to format the phone number")]
public string
FormatExpression {
get {
object b = ViewState["FormatExpression"];
return
(String.IsNullOrEmpty((string)b))
? @"(((\(\d{3}\)
?)|(\d{3}-))?\d{3}-\d{4})|\d{10}|\d{7}" : (string)b;
//return (string)ViewState["FormatExpression"]
?? String.Empty;
}
set {
ViewState["FormatExpression"] =
value;
}
}
[Category("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
PersistenceMode(PersistenceMode.InnerProperty),
Description("The
strongly typed style for the TextBox child control.")]
public Style
PhoneTextBoxStyle {
get {
if(phoneStyle ==
null) {
phoneStyle = new
Style();
}
return phoneStyle;
}
}
#endregion
public PhoneNumberTextCtrl() {
}
protected override
void AddParsedSubObject(object
o) {
// Declaratively specified child controls get added
through this method.
// However, the DatePicker builds its own child
controls, and does not
// want to allow the page developer to add controls,
which could potentially
// mess up the control's collection.
throw new
Exception("Cannot
add child objects declaratively.");
}
protected override
void OnPreRender(EventArgs
e) {
RenderJavaScript();
}
protected override
void CreateChildControls() {
Controls.Clear();
phoneTextBox = new
TextBox();
phoneTextBox.Text = Text;
phoneTextBox.ID = "phoneText";
phoneTextBox.Attributes.Add("onblur",
"formatPhone(this)");
Controls.Add(phoneTextBox);
phoneRequired = new
RequiredFieldValidator();
phoneRequired.Enabled = Required;
phoneRequired.ErrorMessage = RequiredErrorMessage;
phoneRequired.Text = RequiredErrorText;
phoneRequired.ValidationGroup = ValidationGroup;
phoneRequired.ControlToValidate = phoneTextBox.ID;
Controls.Add(phoneRequired);
phoneRegex
= new
RegularExpressionValidator();
phoneRegex.Enabled = FormatRequired;
phoneRegex.ErrorMessage = FormatErrorMessage;
phoneRegex.Text = FormatErrorText;
phoneRegex.ValidationGroup = ValidationGroup;
phoneRegex.ControlToValidate = phoneTextBox.ID;
phoneRegex.ValidationExpression = FormatExpression;
Controls.Add(phoneRegex);
}
protected override
void Render(HtmlTextWriter
writer) {
CreateChildControls();
//EnsureChildControls();
AddAttributesToRender(writer);
if(phoneStyle != null)
{
phoneTextBox.ApplyStyle(phoneStyle);
}
phoneTextBox.RenderControl(writer);
phoneRequired.RenderControl(writer);
phoneRegex.RenderControl(writer);
}
private void
RenderJavaScript() {
String csname2 =
"formatPhone";
Type cstype = this.GetType();
// Get a ClientScriptManager reference from the Page
class.
ClientScriptManager cs = Page.ClientScript;
// Check to see if the client script is already
registered.
if(!cs.IsClientScriptBlockRegistered(cstype,
csname2)) {
StringBuilder sb =
new StringBuilder();
sb.Append("<script type=text/javascript>");
sb.Append("function formatPhone(phoneTextBox){\r\n");
sb.Append("\tvar text = phoneTextBox.value;\r\n");
sb.Append("\ttext = text.replace(/\\D+/g,\"\");\r\n");
sb.Append("\tif(text.length == 10){\r\n");
sb.Append("\t\t phoneTextBox.value = \"(\" +
text.substr(0,3) + \") \" + text.substr(3,3) + \"-\" + text.substr(6,4);\r\n");
sb.Append("\t}\r\n");
sb.Append("\tif(text.length == 7){\r\n");
sb.Append("\t\t phoneTextBox.value =
text.substr(0,3) + \"-\" + text.substr(3,4);\r\n");
sb.Append("\t}\r\n");
sb.Append("}\r\n");
sb.Append("</script>");
cs.RegisterClientScriptBlock(cstype, csname2, sb.ToString(),
false);
}
}
}
}
And
here is the relevant content in the ASPX page. Clearly I’ve not made much use at
all of the various properties of your control:
<%@
Register Assembly="WebControlLibrary1"
Namespace="Controls.TextBoxes"
TagPrefix="cc"%>
...
<cc:PhoneNumberTextCtrl
ID="ctl"
runat="server"
Text="some text">
</cc:PhoneNumberTextCtrl>
The
text value “some text” is perfectly reflected in both the design-time and
runtime rendering. No postback necessary to get expected result. Even when I
programmatically set the Text property in the Page_Load() method, the control
renders correctly because the call to CreateChildControls() updates the Text
property of the child text box by assigning to it the current value of Text
stored in view state.
I don’t know why it doesn’t work for you, but I hope the culprit will soon be found.