在.Net Web应用程序开发中, 我们希望用户在做一个重要的操作时, 能够询问或警告用户. 或者希望我们有这么一个简单实用的控件, 能在用户确定后引发一个服务端的事件.
这个控件的原理很简单,主要是实现IPostBackEventHandler接口和调用Page.GetPostBackEventReference(this, eventArgument), 实现对客户端__doPostBack方法的调用, 引发服务端的事件
而以下这段关键代码是实现功能的核心:
if(AlertString != '') //仅在用户确认后调用客户端的__DostPostBack, 引发服务端事件
{
Action = 'javascript:if(window.confirm(\'' + AlertString + '')==true){';
Action += Page.GetPostBackEventReference(this, 'Click');
Action += ';}';
}
全部代码:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace Booksir.WebControls
{
/// <summary>
/// AlertButton 的摘要说明。
/// </summary>
[
DefaultProperty('Text'),
ToolboxData('<{0}:AlertButton runat=server></{0}:AlertButton>'),
System.ComponentModel.DefaultEvent('Click'),
]
public class AlertButton : System.Web.UI.WebControls.WebControl, IPostBackEventHandler
{
private ViewStateBag StateBag;
public AlertButton()
{
StateBag = new ViewStateBag(this.ViewState);
}
public event EventHandler Click; //事件句柄
public enum AppearanceEnum
{
Button,
ImageButton,
}
/// <summary>
/// 按钮的外观模式
/// </summary>
[
Bindable(false),
Category('Appearance'),
DefaultValue(AppearanceEnum.Button),
Description('按钮的外观模式'),
]
public AppearanceEnum Appearance
{
get
{
object obj;
obj = ViewState['Appearance'];
if(obj == null)
{
Appearance = AppearanceEnum.Button;
return AppearanceEnum.Button;
}
return (AppearanceEnum)obj;
}
set
{
ViewState['Appearance'] = value;
}
}
/// <summary>
/// 在DefaultValue为非常量值的情况下,可以用Reset...来重置属性的默认值
/// </summary>
void ResetAppearance()
{
Appearance = AppearanceEnum.Button;
}
/// <summary>
/// 该方法的存在使系统在属性为默认值不提交属性赋值代码
/// </summary>
/// <returns></returns>
bool ShouldSerializeAppearance()
{
return Appearance != AppearanceEnum.Button;
}
[
Bindable(true),
Category('Appearance'),
DefaultValue('')
]
public string Text
{
get
{
return StateBag.GetString('Text', this.ID);
}
set
{
ViewState['Text'] = value;
}
}
/// <summary>
/// 在执行动作前的提示
/// </summary>
[
Bindable(true),
Category('Appearance'),
DefaultValue(''),
Description('在执行动作前的提示'),
]
public string AlertString
{
get
{
return StateBag.GetString('AlertString', '是否开始执行?');
}
set
{
ViewState['AlertString'] = value;
}
}
/// <summary>
/// 按钮可用时的Image
/// </summary>
[
Description('按钮可用时的Image'),
Category('Appearance'),
Editor(typeof(System.Web.UI.Design.UrlEditor), typeof(System.Drawing.Design.UITypeEditor)),
]
public string EnabledImage
{
get
{
return StateBag.GetString('EnabledImage', '');
}
set
{
ViewState['EnabledImage'] = value;
}
}
/// <summary>
/// 按钮不可用时的Image
/// </summary>
[
Description('按钮不可用时的Image'),
Category('Appearance'),
Editor(typeof(System.Web.UI.Design.UrlEditor), typeof(System.Drawing.Design.UITypeEditor)),
]
public string DisabledImage
{
get
{
return StateBag.GetString('DisabledImage', '');
}
set
{
ViewState['DisabledImage'] = value;
}
}
/// <summary>
/// 将此控件呈现给指定的输出参数。
/// </summary>
/// <param name='output'> 要写出到的 HTML 编写器 </param>
protected override void Render(HtmlTextWriter output)
{
if(Appearance == AppearanceEnum.Button)
output.Write(GetButtonHtml());
else
output.Write(GetImageButtonHtml());
}
/// <summary>
/// 获取呈现Button时的Html
/// </summary>
/// <returns></returns>
private string GetButtonHtml()
{
const string ButtonTag = '<input type=button value='{0}' onclick=\'{1}\' style=\'{2}\'{3} title='{4}'>';
string sHtml;
string Action;
string Style = 'width:{0};height:{1};';
if(AlertString != '')
{
Action = 'javascript:if(window.confirm(\'' + AlertString + '')==true){';
Action += Page.GetPostBackEventReference(this, 'Click');
Action += ';}';
}
else
Action = 'javascript:' + Page.GetPostBackEventReference(this, 'Click');
Style = String.Format
(
Style,
this.Width.ToString(),
this.Height.ToString()
);
Style += this.Attributes['Style'];
sHtml = String.Format
(
ButtonTag,
Text,
Action,
Style,
Enabled ? '' : ' disabled',
this.ToolTip
);
return sHtml;
}
/// <summary>
/// 获取呈现ImageButton时的Html
/// </summary>
/// <returns></returns>
private string GetImageButtonHtml()
{
const string LinkTag = '<a onclick=\'{0}\' title='{1}' style=\'{2}\'>{3}</a>';
const string ImgTag = '<img src='{0}' border=0>';
string sHtml;
string Action;
string Image;
string Style;
if(this.Enabled)
{
if(AlertString != '') //仅在用户确认后调用客户端的__DostPostBack, 引发服务端事件
{
Action = 'javascript:if(window.confirm(\'' + AlertString + '')==true){';
Action += Page.GetPostBackEventReference(this, 'Click');
Action += ';}';
}
else
Action = 'javascript:' + Page.GetPostBackEventReference(this, 'Click');
if(EnabledImage != '')
Image = String.Format(ImgTag, EnabledImage);
else
Image = Text;
}
else
{
Action = 'javascript:void()';
if(DisabledImage != '')
Image = String.Format(ImgTag, DisabledImage);
else
Image = Text;
}
Style = 'cursor:hand;';
Style += this.Attributes['Style'];
sHtml = String.Format
(
LinkTag,
Action,
this.ToolTip,
Style,
Image
);
return sHtml;
}
protected virtual void OnClick()
{
if(Click != null)
Click(this, EventArgs.Empty);
}
public void RaisePostBackEvent(string eventArgument)
{
if(eventArgument == 'Click')
OnClick();
}
}
}
好了, 到此结束, 将以上代码编译为DLL, 并加入为控件吧, 试试看, 是不是简单实用呢?