导出类
• 大多数内置的ASP.NET 服务器控件都会发送一个
HTML 元素。例如,TextBox Web 控件发送一个
<input> 元素,其类型属性设置为text;DataGrid
Web 控件发送一个<table> 元素,为每条要显示的
记录发送<tr> 元素,为每个字段发送<td> 列。
• 但是,不是所有的控件都需要发送HTML 元素。例
如,Repeater 也不将其输出放在HTML 元素中。
• 那些显示为HTML 元素的服务器控件,如TextBox、
Button、DataGrid 等等,是从
System.Web.UI.WebControls.WebControl类导出
的,而那些不产生HTML 元素的控件,如Literal、
Repeater 等,是从System.Web.UI.Control 类导出
的。
1.3 Web控件的特点
• 丰富而一致的对象模型:WebControl
基类实现了对所有控件通用的大量属性,这些
属性包括ForeColor、BackColor、Font、
Enabled 等
• 对浏览器的自动检测:Web 控件能够自
动检测客户机浏览器的功能,并相应地调整它
们所提交的HTML,从而充分发挥浏览器的功
能。
• 数据绑定:在Web 窗体页面中,可以对控
件的任何属性进行数据绑定。
1.4 HTML 控件,WEB控件对比
控件抽象
• HTML 控件不具备任何抽象能力。每种控件与
HTML 标记都是一一对应的
• Web 控件创建了更高级别的抽象,它们没有任何
对应的HTML 标记(如Calendar 和DataGrid)。
因为它们不直接映射为HTML 标记,所以Web 控
件还能够在适当的场合起到合并功能的作用(例如
用一个TextBox 控件来代替多个标记)。这种抽
象为使用第三方提供的种类丰富的控件工具箱打开
了方便之门。
1.4 HTML 控件,WEB控件对比
对象模型
• 对象模型HTML 控件提供了以HTML 为中心的对象模型。
每种控件都包括一个属性集,可以使用该属性集来控制标
记的属性。这个属性集使用了字符串名/值对,并且不是强
类型的。
• Web 控件提供了基于表单的、类似于Visual Basic 的编程
模式。它们也提供了属性集,但它们的主要目标在于提供
一种格式丰富、类型安全且具有一致性的对象模型。每种
Web 控件都包含一组标准的属性,如ForeColor、
BackColor、Font 等Web 控件能够自动对它们生成的结
果进行调整,以确保输出结果在高级浏览器和低级浏览器
上的工作同样出色。Web 控件还能够针对不同的浏览器提
供不同的行为,从而充分发挥浏览器的潜力。例如,
validation 控件还可以通过客户端的脚本来创建用于高级浏
览器的具有高度交互性的页面。
1.4 HTML 控件,WEB控件对比
对生成的HTML 的控制
• HTML 控件允许您完全控制所显示的内
容以及发送到客户机浏览器的内容。
• Web 控件提供了更为丰富的对象模
型,以及适应多种浏览器的能力。因
而,它们没有提供对输出结果的相同程
度的控制能力。
下面是微软的工作人员,给出的商业网站
用手写代码控制表单验证的弊病
• 尽管错误信息或图标经常与输入元素相邻,但是它们几乎
总是位于表的不同单元格中。
• 页面中经常会有一个区域来汇总所有错误。
• 许多站点包含客户端脚本,以便提供更快捷的反馈,同时
防止白白地在与服务器之间往返。
• 许多包含客户端脚本的站点在出现错误时会显示信息框。
• 不仅会验证文本输入,还会验证下拉列表和单选按钮。
• 如果某个字段为空,站点通常会显示与该条目无效时不同
的信息或图标。
• 许多有效性检查可以很好地代替常用的表达式。
• 验证通常是基于两个输入之间的比较结果。
• 90% 或90% 以上的验证任务是一些常见的操作,例如检查
姓名或邮政编码。大多数站点似乎仍在重复进行这些工作。
• 因为站点之间的差别通常太大,无法获得一种完美的解决
方案来处理每个站点的所有验证任务。
2.2 ASP.net进行表单验证的过程
• aspx文件被编译,运行
• 用户输入数据
• 触发Page_Load事件
• 更改Web控件属性,提示哪里没有输入
• 将页面用Html重新输出给用户
• 再次提醒用户输入
2.3验证控件
•验证控件的功能:
• 确保所需字段已经填写
• 确保用户输入的数据未超出给定的范围
• 确保用户输入的数据符合特定的模式
• 根据给定的条件比较两个控件,或把控件的值与
指定的值相比较
• 确保提交页面之前页面上的所有控件都是有效的
正则表达式
• “.”表示任意字符
• “*”表示和其他表达式一起,表示容易组合
• “[A-Z]”表示任意大写字母;
• “/d”表示任意一个数字;
例如:
• /S{6,10} 为6-10位字符
• /d{5} 5位整数
• .*[@#$%^&*/].* 口令必须包含@#$%^&*/ 中的一个
• [a-zA-Z]{6,10} 口令必须由6-10 个字母组成
从ASP.NET 服务器控件插入客户端脚本
• 尽管从技术角度讲,Microsoft® ASP.NET
服务器控件的所有功能都可以在服务器端
执行,但通常情况下通过添加客户端脚本
可以大大增强服务器控件的可用性。例
如,ASP.NET 验证Web 控件可以在服务
器端执行所有的验证检查。但是,对于高
版本浏览器,验证Web 控件也会发送客户
端脚本,以在客户端进行验证。
ASP.NET 服务器控件可以发送两种客户端
脚本:
• 客户端脚本块:客户端脚本块通常是用
JavaScript 编写的,其中通常包含在发生特
定的客户端事件时执行的函数。
• 客户端HTML 属性:客户端HTML 属性提
供将客户端事件与客户端脚本联系在一起
的方法。
ASP.NET 服务器控件中
发送客户端脚本块
使用System.Web.UI.Page 类包含的两个方
法可以将客户端脚本代码发送到由
ASP.NET Web 页面提供的HTML 中:
• RegisterStartupScript(key, script) :在
Web 窗体的结尾处(在</form> 标识之前)
发送脚本块。
• RegisterClientScriptBlock(key, script):在
Web 窗体的开始处(紧接着<form
runat=“server”> 标识之后)发送脚本块。
ASP.
ASP.NET 服务器控件中
发送客户端脚本块
带有指定关键字的脚本块是否已添加到页面中。
• IsStartupScriptRegistered(key)
• IsClientScriptBlockRegistered(key)
使用IsClientScriptBlock() 和IsStartupScript() 方
法。这样一来,验证Web 控件就不会先花时间构
建要发送的客户端代码,而是先检查是否已经存
在使用关键字ValidatorIncludeScript 注册的脚本。
如果存在,控件就会放弃构建客户端脚本块,因
为脚本块已经由页面上的其他验证控件构建了。
namespace ClientSideScript
{
/// <summary>
/// WebCustomControl1 的摘要说明。
/// </summary>
[DefaultProperty("PopupMessage"),
ToolboxData("<{0}:PopupGreeting runat=server></{0}:PopupGreeting >")]
public class PopupGreeting : System.Web.UI.Control
{
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public string PopupMessage
{
get
{
//检查ViewState中是否存在该项目
object popupMessage = this.ViewState["PopupMessage"];
if (popupMessage != null)
return this.ViewState["PopupMessage"].ToString();
else
return "Welcome to my Web site!";
}
set
{
// 指定 ViewState 变量
ViewState["PopupMessage"] = value;
}
}
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public bool Enabled
{
get
{
// 检查 ViewState 中是否存在该项目
object enabled = this.ViewState["Enabled"];
if (enabled != null)
return (bool) this.ViewState["Enabled"];
else
return true;
}
set
{
// 指定 ViewState 变量
ViewState["Enabled"] = value;
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
string scriptKey = "intoPopupMessage:" + this.UniqueID;
if (!Page.IsStartupScriptRegistered(scriptKey) && this.Enabled &&
!Page.IsPostBack)
{
string scriptBlock =
@"<script language=""JavaScript"">
<!--
alert(""%%POPUP_MESSAGE%%"");
// -->
</script>";
//1、客户端脚本块包含在 HTML 注释(<!-- 和 -->)中。之所以这样,是因为如果
//不将脚本块放入 HTML 注释中,那些不能识别脚本的旧式浏览器就会显示 <script> 块的内容。
//2、脚本块中 HTML 注释的结束标记前有一个 JavaScript 注释,即 //。这是因为旧版本
//的 Netscape 在遇到 --> 时,会抛出 JavaScript 分析异常,因此必须将其注释掉。
scriptBlock = scriptBlock.Replace("%%POPUP_MESSAGE%%", this.PopupMessage);
Page.RegisterStartupScript(scriptKey, scriptBlock);
}
}
}
namespace ClientSideScript
{
/// <summary>
/// ConfirmButton 的摘要说明。
/// </summary>
[DefaultProperty("PopupMessage"),
ToolboxData("<{0}:ConfirmButton runat=server></{0}:ConfirmButton>")]
public class ConfirmButton : Button
{
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public string PopupMessage
{
get
{
// 检查 ViewState 中是否存在该项目
object popupMessage = this.ViewState["PopupMessage"];
if (popupMessage != null)
return this.ViewState["PopupMessage"].ToString();
else
return "真的要删除吗?";
}
set
{
// 指定 ViewState 变量
ViewState["PopupMessage"] = value;
}
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
string script = @"return confirm(""%%POPUP_MESSAGE%%"");";
script = script.Replace("%%POPUP_MESSAGE%%",
this.PopupMessage.Replace("/"", "///""));
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, script);
}
}
}
// 在此处放置用户代码以初始化页面
string script = @"return confirm('真的要删除吗?');";
this.Button1.Attributes.Add("onclick",script);
TreeView IE Web 控件入门
• 当TreeView IE Web 控件在访问者浏览器中显示
时,会显示一棵树,此树与Windows 资源管理器
中的树非常类似。不同的是,TreeView 可以由任
意多个TreeNode 对象组成。每个TreeNode 对
象都可以关联文本和图像。
• TreeNodeType定义一个节点类型,适用于
TreeView中的一个或一组节点。
• 另外,TreeNode 还可以显示为超链接并与某个
URL 相关联。每个TreeNote 还可以包括任意多
个子TreeNote 对象。包含TreeNode 及其子节
点的层次结构构成了TreeView 控件所呈现的树
结构。
using Microsoft.Web.UI.WebControls;
namespace WebControlExample
{
/// <summary>
/// UseTreeView 的摘要说明。
/// </summary>
public class UseTreeView : System.Web.UI.Page
{
protected Microsoft.Web.UI.WebControls.TreeView tv1;
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.TextBox tbMain;
protected System.Web.UI.WebControls.Button btnFind;
protected System.Web.UI.WebControls.Label myLabel;
protected Microsoft.Web.UI.WebControls.TreeView tvXML;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
if(!IsPostBack)
init();
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.tvXML.Expand += new Microsoft.Web.UI.WebControls.ClickEventHandler(this.tvXML_Expand);
this.tvXML.SelectedIndexChange += new Microsoft.Web.UI.WebControls.SelectEventHandler(this.tvXML_SelectedIndexChange);
this.tvXML.Collapse += new Microsoft.Web.UI.WebControls.ClickEventHandler(this.tvXML_Collapse);
this.btnFind.Click += new System.EventHandler(this.btnFind_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void tvXML_Expand(object sender, Microsoft.Web.UI.WebControls.TreeViewClickEventArgs e)
{
myLabel.Text = "已展开 (节点索引= " + e.Node.ToString() + ")";
}
private void tvXML_Collapse(object sender, Microsoft.Web.UI.WebControls.TreeViewClickEventArgs e)
{
myLabel.Text = "已折叠 (节点索引= " + e.Node.ToString() + ")";
}
private void tvXML_SelectedIndexChange(object sender, Microsoft.Web.UI.WebControls.TreeViewSelectEventArgs e)
{
myLabel.Text = "已选中"+e.NewNode.ToString() + " (旧节点索引=" + e.OldNode.ToString()+")" ;
}
private void btnFind_Click(object sender, System.EventArgs e)
{
Find(tv1.Nodes);
}
private void Find(TreeNodeCollection tnc)
{
foreach(TreeNode node in tnc)
{
if(node.Nodes.Count!=0)
Find(node.Nodes);
if(node.Text==tbMain.Text)
{
string index1=node.GetNodeIndex();//取得index
tv1.SelectedNodeIndex=index1;
return;
}
}
}
private void init()
{
string strTreeName = "tvXML";
string strRef = Page.GetPostBackEventReference(tvXML);
string strScript = "<script language=/'javascript/'> " +"<!-- "
+ " function initTree() { "
+ " " + strTreeName + ".onSelectedIndexChange = function() { "
+ " if (event.oldTreeNodeIndex != event.newTreeNodeIndex) "
+ " this.queueEvent(/'onselectedindexchange/', event.oldTreeNodeIndex + /',/' + event.newTreeNodeIndex); "
+ " window.setTimeout(/'" + strRef.Replace("/'", "///'") + "/', 0, /'javascript/'); "
+ " } "
+ " } "
+ "// --> "
+ "</script>";
Page.RegisterClientScriptBlock("InitTree",strScript);
}
}
}
//建树的基本思路是:从根节点开始递归调用显示子树
private void InitTree(TreeNodeCollection Nds,string parentId)
{
DataView dv=new DataView();
TreeNode tmpNd;
string intId;
dv.Table=ds.Tables["tree"];
dv.RowFilter="ParentId='" + parentId + "'" ;
foreach(DataRowView drv in dv)
{
tmpNd=new TreeNode();
tmpNd.ID=drv["NodeId"].ToString();
tmpNd.Text=drv["NodeName"].ToString();
tmpNd.ImageUrl="../images/"+drv["Icon"].ToString();
tmpNd.NavigateUrl="../"+drv["Address"].ToString();
Nds.Add(tmpNd);
intId=drv["ParentId"].ToString();
InitTree(tmpNd.Nodes,tmpNd.ID);
}
}
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Drawing;
namespace myCalendar
{
/// <summary>
/// WebCustomControl1 的摘要说明。
/// </summary>
[DefaultProperty("Text"),
ToolboxData("<{0}:DatePicker runat=server></{0}:DatePicker >")]
public class DatePicker : System.Web.UI.WebControls.WebControl, IPostBackEventHandler
{
//选择日期按钮的默认样式
private const string _BUTTONDEFAULTSTYLE = "BORDER-RIGHT: gray 1px solid; BORDER-TOP: gray 1px solid; BORDER-LEFT: gray 1px solid; CURSOR: hand; BORDER-BOTTOM: gray 1px solid;";
//按钮默认文本
private const string _BUTTONDEFAULTTEXT = "...";
private System.Web.UI.WebControls.Calendar _Calendar;
public override ControlCollection Controls
{
get
{
EnsureChildControls(); //确认子控件集都已被创建
return base.Controls;
}
}
//创建子控件(服务器日历控件)
protected override void CreateChildControls()
{
Controls.Clear();
_Calendar = new Calendar();
_Calendar.ID = MyCalendarID;
_Calendar.SelectedDate = DateTime.Parse(Text);
_Calendar.TitleFormat = TitleFormat.MonthYear;
_Calendar.NextPrevFormat = NextPrevFormat.ShortMonth;
_Calendar.CellSpacing = 0;
_Calendar.Font.Size = FontUnit.Parse("9pt");
_Calendar.Font.Name = "Verdana";
_Calendar.SelectedDayStyle.BackColor = ColorTranslator.FromHtml("#333399");
_Calendar.SelectedDayStyle.ForeColor = ColorTranslator.FromHtml("White");
_Calendar.DayStyle.BackColor = ColorTranslator.FromHtml("#CCCCCC");
_Calendar.TodayDayStyle.BackColor = ColorTranslator.FromHtml("#999999");
_Calendar.TodayDayStyle.ForeColor = ColorTranslator.FromHtml("Aqua");
_Calendar.DayHeaderStyle.Font.Size = FontUnit.Parse("8pt");
_Calendar.DayHeaderStyle.Font.Bold = true;
_Calendar.DayHeaderStyle.Height = Unit.Parse("8pt");
_Calendar.DayHeaderStyle.ForeColor = ColorTranslator.FromHtml("#333333");
_Calendar.NextPrevStyle.Font.Size = FontUnit.Parse("8pt");
_Calendar.NextPrevStyle.Font.Bold = true;
_Calendar.NextPrevStyle.ForeColor = ColorTranslator.FromHtml("White");
_Calendar.TitleStyle.Font.Size = FontUnit.Parse("12pt");
_Calendar.TitleStyle.Font.Bold = true;
_Calendar.TitleStyle.Height = Unit.Parse("12pt");
_Calendar.TitleStyle.ForeColor = ColorTranslator.FromHtml("White");
_Calendar.TitleStyle.BackColor = ColorTranslator.FromHtml("#333399");
_Calendar.OtherMonthDayStyle.ForeColor = ColorTranslator.FromHtml("#999999");
_Calendar.NextPrevFormat = NextPrevFormat.CustomText;
_Calendar.NextMonthText = "下月";
_Calendar.PrevMonthText = "上月";
_Calendar.Style.Add("display","none"); //默认不显示下拉日历控件
_Calendar.SelectionChanged += new EventHandler(_Calendar_SelectionChanged);
this.Controls.Add(_Calendar);
}
[
Category("Appearance"), //该属性所属类别
DefaultValue(""), //属性默认值
Description("设置该日期控件的值。") //属性的描述
]
public string Text
{
get
{
EnsureChildControls();
return (ViewState["Text"] == null)?System.DateTime.Today.ToString("yyyy-MM-dd"):ViewState["Text"].ToString();
}
set
{
EnsureChildControls();
DateTime dt = System.DateTime.Today;
try
{
dt = DateTime.Parse(value);
}
catch
{
throw new ArgumentOutOfRangeException("请输入日期型字符串(例如:1981-04-29)!");
}
ViewState["Text"] = dt.ToString("yyyy-MM-dd");
}
}
//重载服务器控件的Enabled属性,将选择日期按钮变灰(禁用)
public override bool Enabled
{
get
{
EnsureChildControls();
return ViewState["Enabled"] == null?true:(bool)ViewState["Enabled"];
}
set
{
EnsureChildControls();
ViewState["Enabled"] = value;
}
}
public string ButtonStyle
{
get
{
EnsureChildControls();
object o = ViewState["ButtonSytle"];
return (o == null)?_BUTTONDEFAULTSTYLE:o.ToString();
}
set
{
EnsureChildControls();
ViewState["ButtonSytle"] = value;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public string MyCalendarID //复合控件ID
{
get
{
EnsureChildControls();
return this.ClientID+"_MyCalendar";
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public string MyCalendarName //复合控件名称
{
get
{
EnsureChildControls();
return this.UniqueID+":MyCalendar";
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public string DatePickerInputID //复合控件中输入框的ID
{
get
{
EnsureChildControls();
return this.ClientID+"_DateInput";
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public string DatePickerInputName //复合控件中输入框的名称
{
get
{
EnsureChildControls();
return this.UniqueID+":DateInput";
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public string DatePickerButtonID //复合控件中按钮的ID
{
get
{
EnsureChildControls();
return this.ClientID+"_DateButton";
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public string DatePickerButtonName //复合控件中按钮的名称
{
get
{
EnsureChildControls();
return this.UniqueID+":DateButton";
}
}
public string ButtonText
{
get
{
EnsureChildControls();
return ViewState["ButtonText"] == null?_BUTTONDEFAULTTEXT:(string)ViewState["ButtonText"];
}
set
{
EnsureChildControls();
ViewState["ButtonText"] = value;
}
}
/// <summary>
/// /// 将此控件呈现给指定的输出参数。
/// </summary>
/// /// <param name="output"> 要写出到的 HTML 编写器 </param>
///
protected override void Render(HtmlTextWriter output)
{
//在页面中输出控件时,产生一个表格(二行二列),以下是表格的样式
output.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
output.AddAttribute(HtmlTextWriterAttribute.Border, "0");
output.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
output.AddStyleAttribute("LEFT", this.Style["LEFT"]);
output.AddStyleAttribute("TOP", this.Style["TOP"]);
output.AddStyleAttribute("POSITION", "absolute");
if (Width != Unit.Empty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.Width, Width.ToString());
}
else
{
output.AddStyleAttribute(HtmlTextWriterStyle.Width, "200px");
}
output.RenderBeginTag(HtmlTextWriterTag.Table); //输出表格
output.RenderBeginTag(HtmlTextWriterTag.Tr); //表格第一行
output.AddAttribute(HtmlTextWriterAttribute.Width, "90%");
output.RenderBeginTag(HtmlTextWriterTag.Td);
//以下是第一行第一列中文本框的属性及其样式设置
if (!Enabled)
{
output.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "true");
}
output.AddAttribute(HtmlTextWriterAttribute.Type, "Text");
output.AddAttribute(HtmlTextWriterAttribute.Id, DatePickerInputID);
output.AddAttribute(HtmlTextWriterAttribute.Name, DatePickerInputName);
output.AddAttribute(HtmlTextWriterAttribute.Value, Text);
output.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
output.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%");
output.AddStyleAttribute(HtmlTextWriterStyle.FontFamily, Font.Name);
output.AddStyleAttribute(HtmlTextWriterStyle.FontSize, Font.Size.ToString());
output.AddStyleAttribute(HtmlTextWriterStyle.FontWeight, Font.Bold?"bold":"");
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(BackColor));
output.AddStyleAttribute(HtmlTextWriterStyle.Color, ColorTranslator.ToHtml(ForeColor));
output.RenderBeginTag(HtmlTextWriterTag.Input); //输出文本框
output.RenderEndTag();
output.RenderEndTag();
output.AddAttribute(HtmlTextWriterAttribute.Width, "*");
output.RenderBeginTag(HtmlTextWriterTag.Td);
//以下是第一行第二列中按钮的属性及其样式设置
if (!Enabled)
{
output.AddAttribute(HtmlTextWriterAttribute.Disabled, "true");
}
output.AddAttribute(HtmlTextWriterAttribute.Type, "Submit");
output.AddAttribute(HtmlTextWriterAttribute.Id, DatePickerButtonID);
output.AddAttribute(HtmlTextWriterAttribute.Name, DatePickerButtonName);
output.AddAttribute(HtmlTextWriterAttribute.Value, ButtonText);
output.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
output.AddAttribute(HtmlTextWriterAttribute.Onclick, Page.GetPostBackEventReference(this)); //点击按钮时需要回传服务器来触发后面的OnClick事件
output.AddAttribute(HtmlTextWriterAttribute.Style, ButtonStyle);
output.RenderBeginTag(HtmlTextWriterTag.Input); //输出按钮
output.RenderEndTag();
output.RenderEndTag();
output.RenderEndTag();
output.RenderBeginTag(HtmlTextWriterTag.Tr);
output.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
output.RenderBeginTag(HtmlTextWriterTag.Td);
_Calendar.RenderControl(output); //将日历子控件输出
output.RenderEndTag();
output.RenderEndTag();
output.RenderEndTag();
}
//复合控件必须继承IpostBackEventHandler接口,才能继承RaisePostBackEvent事件
public void RaisePostBackEvent(string eventArgument)
{
OnClick(EventArgs.Empty);
}
protected virtual void OnClick(EventArgs e)
{
//点击选择日期按钮时,如果日历子控件没有显示则显示出来并将文本框的值赋值给日历子控件
if (_Calendar.Attributes["display"] != "")
{
_Calendar.SelectedDate = DateTime.Parse(Text);
_Calendar.Style.Add("display","");
}
}
//复合控件中的日历控件日期变化事件
private void _Calendar_SelectionChanged(object sender, EventArgs e)
{
//当选择的日期变化时,将所选日期赋值给文本框并将日历子控件隐藏
Text = _Calendar.SelectedDate.ToString();
_Calendar.Style.Add("display","none");
}
}
}