现在,我们就来改写AddAttributesToRender方法,ASP.NET在渲染该控件到输出时,会调用该方法我们所改写的方法,以达到将JS代码发送到客户端的目的。具体代码如下:
protected override void AddAttributesToRender(HtmlTextWriter writer) { System.Text.StringBuilder ClientSideEventReference = new System.Text.StringBuilder();
if (((this.Page != null) && this.CausesValidation) && (this.Page.Validators.Count > 0)) { ClientSideEventReference.Append("if (typeof(Page_ClientValidate) == 'function'){if (Page_ClientValidate() == false){return false;}}"); } //ShowMessageBox? if (this.ShowMessageBox) { ClientSideEventReference.Append("if (!confirm('" + this.WarningText + "')){return false}"); } ClientSideEventReference.AppendFormat("this.value = '{0}';", (string)this.ViewState["afterSubmitText"]); ClientSideEventReference.Append("this.disabled = true;"); ClientSideEventReference.Append(this.Page.ClientScript.GetPostBackEventReference(this, string.Empty));
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, ClientSideEventReference.ToString(), true); base.AddAttributesToRender(writer); }
|
我们把发送到客户端的js代码看作是一个字符串,为了提高性能,用StringBuilder来对象来构造这个字符串。
首先根据页面对象存在且控件启用了验证(该属性从父继承),且页面对象的验证器内计数大于0来决定输出一段引发验证的js代码,
根据ShowMessageBox属性来决定输出一个弹出提示的代码,并且弹出提示的内容由WarningText属性给出。
书写一个js脚本为按钮赋值为提交后文本,并且将按钮设置为禁用以变灰色。
最后附加一段由ASP.NET提供的用于影射回调事件引用的js脚本(this.Page.ClientScript.GetPostBackEventReference(this, string.Empty)方法将返回一个回送事件引用的js脚本字符串)
将StringBuilder对象内构造的字符串用HtmlTextWriter对象的AddAttribute方法写入按钮的OnClick事件中。
调用父类的AddAttributesToRender方法让父类有机会完成其他的配置等操作。
完整的ClickOnceButton代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls;
namespace BlogLan.Web.Controls { /// <summary> /// 表示一个防止重复提交的按钮。当用户单击按钮以后,该按钮变灰,不能再次单击,直到重新加载页面或者跳转。 /// </summary> [DefaultProperty("Text")] [ToolboxData("<{0}:ClickOnceButton runat=server></{0}:ClickOnceButton>")] public class ClickOnceButton : System.Web.UI.WebControls.Button { /// <summary> /// 默认的构造函数。 /// </summary> public ClickOnceButton() { this.ViewState["afterSubmitText"] = "正在提交,请稍候..."; base.Text = "ClickOnceButton"; this.ViewState["showMessageBox"] = false; this.ViewState["warningText"] = "确定要提交吗?"; }
/// <summary> /// 获取或设置单击按钮后,按钮上所显示的文本。 /// </summary> [Bindable(true), Category("Appearance"), DefaultValue("正在提交,请稍候..."), Description("指示单击提交后,按钮上所显示的文本。")] public string AfterSubmitText { get { string afterSubmitText = (string)this.ViewState["afterSubmitText"]; if (afterSubmitText != null) { return afterSubmitText; } else { return string.Empty; } } set { this.ViewState["afterSubmitText"] = value; } }
[Bindable(true), Category("Appearance"), DefaultValue(false), Description("指示是否要显示一个提示框。")] public bool ShowMessageBox { get { return (bool)this.ViewState["showMessageBox"]; } set { this.ViewState["showMessageBox"] = value; } }
[Bindable(true), Category("Appearance"), DefaultValue("确定要提交吗?"), Description("指示提示框内所包含的内容。")] public string WarningText { get { return (string)this.ViewState["warningText"]; } set { this.ViewState["warningText"] = value; } }
/// <summary> /// AddAttributesToRender /// </summary> /// <param name="writer">HtmlTextWriter</param> protected override void AddAttributesToRender(HtmlTextWriter writer) { System.Text.StringBuilder ClientSideEventReference = new System.Text.StringBuilder();
if (((this.Page != null) && this.CausesValidation) && (this.Page.Validators.Count > 0)) { ClientSideEventReference.Append("if (typeof(Page_ClientValidate) == 'function'){if (Page_ClientValidate() == false){return false;}}"); } //ShowMessageBox? if (this.ShowMessageBox) { ClientSideEventReference.Append("if (!confirm('" + this.WarningText + "')){return false}"); } ClientSideEventReference.AppendFormat("this.value = '{0}';", (string)this.ViewState["afterSubmitText"]); ClientSideEventReference.Append("this.disabled = true;"); ClientSideEventReference.Append(this.Page.ClientScript.GetPostBackEventReference(this, string.Empty));
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, ClientSideEventReference.ToString(), true); base.AddAttributesToRender(writer); } } }
|
你可以把它编译为dll,放置在工具箱中,随意拖放到网页上即可使用。因为继承了Button控件,它拥有Button的全部特性,并且自动继承了Button的设计时支持。