%@ Page Language="C#" AutoEventWireup="true" CodeBehind="控件属性在页面源码中的表达方式.aspx.cs"
Inherits="CustomServerControlTest.控件属性在页面源码中的表达方式" %
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
html xmlns="http://www.w3.org/1999/xhtml"
head runat="server"
title 控件属性在页面源码中的表达方式 /title
/head
body
form id="form1" runat="server"
div id="divOperation"
当前页面所在程序集:
%
1: =System.Reflection.Assembly.GetExecutingAssembly().Location
%
/div
!-- ------------------------------------------------------------分割线------------------------------------------------------------ --
div id="divDemo"
asp:Label ID="Label1" runat="server" Text="Hello Label!" /asp:Label
asp:Label ID="Label2" runat="server" Hello Label! /asp:Label
asp:Label ID="Label3" runat="server" Text="Hello Label!" Font-Bold="true" Font-Size="14" /asp:Label
asp:TextBox ID="TextBox1" runat="server" Hello TextBox! /asp:TextBox
asp:Panel ID="Panel1" runat="server" Hello Panel! /asp:Panel
asp:DropDownList ID="ddlGender" runat="server"
asp:ListItem Value="1" 男 /asp:ListItem
asp:ListItem Value="0" 女 /asp:ListItem
/asp:DropDownList
asp:GridView ID="Gridview1" runat="server" AutoGenerateColumns="False" EnableModelValidation="True"
Columns
asp:BoundField HeaderText="HeaderText1" /
asp:CheckBoxField HeaderText="HeaderText2" /
/Columns
EditRowStyle BackColor="Red" /
/asp:GridView
/div
!-- ------------------------------------------------------------分割线------------------------------------------------------------ --
/form
/body
/html
public class 控件属性在页面源码中的表达方式_aspx : 控件属性在页面源码中的表达方式, IRequiresSessionState, IHttpHandler
{
private static bool __initialized;
private static object __fileDependencies;
protected DefaultProfile Profile
{
get
{
return (DefaultProfile)this.Context.Profile;
}
}
protected HttpApplication ApplicationInstance
{
get
{
return this.Context.ApplicationInstance;
}
}
[DebuggerNonUserCode]
public 控件属性在页面源码中的表达方式_aspx()
{
base.AppRelativeVirtualPath = "~/控件属性在页面源码中的表达方式.aspx";
if (!控件属性在页面源码中的表达方式_aspx.__initialized)
{
控件属性在页面源码中的表达方式_aspx.__fileDependencies = base.GetWrappedFileDependencies(new string[]
{
"~/控件属性在页面源码中的表达方式.aspx"
});
控件属性在页面源码中的表达方式_aspx.__initialized = true;
}
base.Server.ScriptTimeout = 30000000;
}
[DebuggerNonUserCode]
private HtmlTitle __BuildControl__control3()
{
return new HtmlTitle();
}
[DebuggerNonUserCode]
private HtmlHead __BuildControl__control2()
{
HtmlHead __ctrl = new HtmlHead("head");
HtmlTitle __ctrl2 = this.__BuildControl__control3();
IParserAccessor __parser = __ctrl;
__parser.AddParsedSubObject(__ctrl2);
return __ctrl;
}
//--------------------------------------------------------------分割线--------------------------------------------------------------
[DebuggerNonUserCode]
private Label __BuildControlLabel1()
{
Label __ctrl = new Label();
this.Label1 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "Label1";
__ctrl.Text = "Hello Label!";
return __ctrl;
}
[DebuggerNonUserCode]
private Label __BuildControlLabel2()
{
Label __ctrl = new Label();
this.Label2 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "Label2";
IParserAccessor __parser = __ctrl;
__parser.AddParsedSubObject(new LiteralControl("Hello Label!"));
return __ctrl;
}
[DebuggerNonUserCode]
private Label __BuildControlLabel3()
{
Label __ctrl = new Label();
this.Label3 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "Label3";
__ctrl.Text = "Hello Label!";
__ctrl.Font.Bold = true;
__ctrl.Font.Size = new FontUnit(new Unit(14.0, UnitType.Point));
return __ctrl;
}
[DebuggerNonUserCode]
private TextBox __BuildControlTextBox1()
{
TextBox __ctrl = new TextBox();
this.TextBox1 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "TextBox1";
__ctrl.Text = "Hello TextBox!";
return __ctrl;
}
[DebuggerNonUserCode]
private Panel __BuildControlPanel1()
{
Panel __ctrl = new Panel();
this.Panel1 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "Panel1";
IParserAccessor __parser = __ctrl;
__parser.AddParsedSubObject(new LiteralControl("Hello Panel!"));
return __ctrl;
}
[DebuggerNonUserCode]
private ListItem __BuildControl__control5()
{
return new ListItem
{
Value = "1",
Text = "男"
};
}
[DebuggerNonUserCode]
private ListItem __BuildControl__control6()
{
return new ListItem
{
Value = "0",
Text = "女"
};
}
[DebuggerNonUserCode]
private void __BuildControl__control4(ListItemCollection __ctrl)
{
ListItem __ctrl2 = this.__BuildControl__control5();
__ctrl.Add(__ctrl2);
ListItem __ctrl3 = this.__BuildControl__control6();
__ctrl.Add(__ctrl3);
}
[DebuggerNonUserCode]
private DropDownList __BuildControlddlGender()
{
DropDownList __ctrl = new DropDownList();
this.ddlGender = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "ddlGender";
this.__BuildControl__control4(__ctrl.Items);
return __ctrl;
}
[DebuggerNonUserCode]
private BoundField __BuildControl__control8()
{
return new BoundField
{
HeaderText = "HeaderText1"
};
}
[DebuggerNonUserCode]
private CheckBoxField __BuildControl__control9()
{
return new CheckBoxField
{
HeaderText = "HeaderText2"
};
}
[DebuggerNonUserCode]
private void __BuildControl__control7(DataControlFieldCollection __ctrl)
{
BoundField __ctrl2 = this.__BuildControl__control8();
__ctrl.Add(__ctrl2);
CheckBoxField __ctrl3 = this.__BuildControl__control9();
__ctrl.Add(__ctrl3);
}
[DebuggerNonUserCode]
private void __BuildControl__control10(TableItemStyle __ctrl)
{
__ctrl.BackColor = Color.Red;
}
[DebuggerNonUserCode]
private GridView __BuildControlGridview1()
{
GridView __ctrl = new GridView();
this.Gridview1 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "Gridview1";
__ctrl.AutoGenerateColumns = false;
__ctrl.EnableModelValidation = true;
this.__BuildControl__control7(__ctrl.Columns);
this.__BuildControl__control10(__ctrl.EditRowStyle);
return __ctrl;
}
//--------------------------------------------------------------分割线--------------------------------------------------------------
[DebuggerNonUserCode]
private HtmlForm __BuildControlform1()
{
HtmlForm __ctrl = new HtmlForm();
this.form1 = __ctrl;
__ctrl.ID = "form1";
Label __ctrl2 = this.__BuildControlLabel1();
IParserAccessor __parser = __ctrl;
__parser.AddParsedSubObject(__ctrl2);
Label __ctrl3 = this.__BuildControlLabel2();
__parser.AddParsedSubObject(__ctrl3);
Label __ctrl4 = this.__BuildControlLabel3();
__parser.AddParsedSubObject(__ctrl4);
TextBox __ctrl5 = this.__BuildControlTextBox1();
__parser.AddParsedSubObject(__ctrl5);
Panel __ctrl6 = this.__BuildControlPanel1();
__parser.AddParsedSubObject(__ctrl6);
DropDownList __ctrl7 = this.__BuildControlddlGender();
__parser.AddParsedSubObject(__ctrl7);
GridView __ctrl8 = this.__BuildControlGridview1();
__parser.AddParsedSubObject(__ctrl8);
__ctrl.SetRenderMethodDelegate(new RenderMethod(this.__Renderform1));
return __ctrl;
}
private void __Renderform1(HtmlTextWriter __w, Control parameterContainer)
{
__w.Write("\r\n div id=\"divOperation\" \r\n 当前页面所在程序集:\r\n ");
__w.Write(Assembly.GetExecutingAssembly().Location);
__w.Write("\r\n /div \r\n \r\n div id=\"divDemo\" \r\n ");
parameterContainer.Controls[0].RenderControl(__w);
__w.Write("\r\n ");
parameterContainer.Controls[1].RenderControl(__w);
__w.Write("\r\n ");
parameterContainer.Controls[2].RenderControl(__w);
__w.Write("\r\n ");
parameterContainer.Controls[3].RenderControl(__w);
__w.Write("\r\n ");
parameterContainer.Controls[4].RenderControl(__w);
__w.Write("\r\n ");
parameterContainer.Controls[5].RenderControl(__w);
__w.Write("\r\n ");
parameterContainer.Controls[6].RenderControl(__w);
__w.Write("\r\n /div \r\n ");
}
[DebuggerNonUserCode]
private void __BuildControlTree(控件属性在页面源码中的表达方式_aspx __ctrl)
{
this.InitializeCulture();
((IParserAccessor)__ctrl).AddParsedSubObject(new LiteralControl("\r\n\r\n !DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\" \r\n html xmlns=\"http://www.w3.org/1999/xhtml\" \r\n"));
HtmlHead __ctrl2 = this.__BuildControl__control2();
((IParserAccessor)__ctrl).AddParsedSubObject(__ctrl2);
((IParserAccessor)__ctrl).AddParsedSubObject(new LiteralControl("\r\n body \r\n "));
HtmlForm __ctrl3 = this.__BuildControlform1();
((IParserAccessor)__ctrl).AddParsedSubObject(__ctrl3);
((IParserAccessor)__ctrl).AddParsedSubObject(new LiteralControl("\r\n /body \r\n /html \r\n"));
}
[DebuggerNonUserCode]
protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
this.__BuildControlTree(this);
base.AddWrappedFileDependencies(控件属性在页面源码中的表达方式_aspx.__fileDependencies);
base.Request.ValidateInput();
}
[DebuggerNonUserCode]
public override int GetTypeHashCode()
{
return -1997224554;
}
[DebuggerNonUserCode]
public override void ProcessRequest(HttpContext context)
{
base.ProcessRequest(context);
}
}
}
//------------------------------------------------------------------------------
// 自动生成
// 此代码由工具生成。
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// /自动生成
//------------------------------------------------------------------------------
namespace CustomServerControlTest
{
public partial class 控件属性在页面源码中的表达方式
{
/// summary
/// form1 控件。
/// /summary
/// remarks
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// /remarks
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
/// summary
/// Label1 控件。
/// /summary
/// remarks
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// /remarks
protected global::System.Web.UI.WebControls.Label Label1;
/// summary
/// Label2 控件。
/// /summary
/// remarks
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// /remarks
protected global::System.Web.UI.WebControls.Label Label2;
/// summary
/// Label3 控件。
/// /summary
/// remarks
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// /remarks
protected global::System.Web.UI.WebControls.Label Label3;
/// summary
/// TextBox1 控件。
/// /summary
/// remarks
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// /remarks
protected global::System.Web.UI.WebControls.TextBox TextBox1;
/// summary
/// Panel1 控件。
/// /summary
/// remarks
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// /remarks
protected global::System.Web.UI.WebControls.Panel Panel1;
/// summary
/// ddlGender 控件。
/// /summary
/// remarks
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// /remarks
protected global::System.Web.UI.WebControls.DropDownList ddlGender;
/// summary
/// Gridview1 控件。
/// /summary
/// remarks
/// 自动生成的字段。
/// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
/// /remarks
protected global::System.Web.UI.WebControls.GridView Gridview1;
}
}
asp:Label ID="Label3" runat="server" Text="Hello Label!" Font-Bold="true" Font-Size="14" /asp:Label
asp:GridView ID="Gridview1" runat="server" AutoGenerateColumns="False" EnableModelValidation="True"
Columns
asp:BoundField HeaderText="HeaderText1" /
asp:CheckBoxField HeaderText="HeaderText2" /
/Columns
EditRowStyle BackColor="Red" /
/asp:GridView
开始之前,先看一下概念,什么是嵌套内容?嵌套内容是指服务器起始标签与服务器结束标签间的元素集。
们对比对应表中②、④发现同样是嵌套内容,有的被解析成了属性,有的被解析成了子控件。这种对服务器控件标记中嵌套内容的解析行为是怎么控制的呢?
ParseChildrenAttribute:是一个类级别的属性。使用 ParseChildrenAttribute 类指示页分析器应如何处理页上声明的服务器控件标记中的嵌套内容。
命名空间:System.Web.UI
程序集:System.Web(在 system.web.dll 中)
ParseChildrenAttribute类的构造函数有以下四个重载版本:
TextBox因为装饰了[ParseChildren(true, "Text")]而将其嵌套内容解析成属性值,并赋值给Text属性:
public class TextBox : WebControl, IPostBackDataHandler, IEditableTextControl, ITextControl
{
//... ...
}
PersistChildrenAttribute:是一个类级别的属性,使用 PersistChildrenAttribute类指示设计器应如何处理页上声明的服务器控件标记中的嵌套内容。
命名空间:System.Web.UI
程序集:System.Web(在 system.web.dll 中)
注:ParseChildrenAttribute和PersistChildrenAttribute常同时出现,ParseChildrenAttribute将对控件标签内嵌套内容的解析行为告知页分析器;PersistChildrenAttribute将对控件标签内嵌套内容的解析行为告知设计器,但两者构造函数的参数的意义不同。ParseChildrenAttribute的参数为ChildrenAsProperties ,表示是否解析为属性;PersistChildrenAttribute的参数为persist,表示是否将嵌套内容作为嵌套控件保持。所以控件上如果出现[ParseChildren(false)]就会出现[PersistChildren(true)],反之亦然。
PersistenceModeAttribute:是一个元素级别的属性。用于指定控件属性的保存(持久化)方式,它接受一个枚举类型参数:PersistenceMode,其枚举值及意义如下表:
①EncodedInnerDefaultProperty:
们上面说到TextBox因为装饰了[ParseChildren(true, "Text")]而将其嵌套内容解析成Text属性的属性值,相应的TextBox的Text属性也被修饰上了[PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)],使得Text成为TextBox唯一嵌套内容,而且如果嵌套内容中存在标签格式的文本,解析器页不会把这些标签进行进一步解析。
public class TextBox : WebControl, IPostBackDataHandler, IEditableTextControl, ITextControl
{
//... ...
[PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)]
public virtual string Text
{
//... ...
}
//... ...
}
②InnerDefaultProperty:
们再看DropDownList的父类ListControl。它装饰了[ParseChildren(true, "Items")]而将其嵌套内容解析成Items属性的属性值,相应的ListControl的Text属性也被修饰上了[PersistenceMode(PersistenceMode.InnerDefaultProperty)],使得Items成为ListControl唯一嵌套内容。
public abstract class ListControl : DataBoundControl, IEditableTextControl, ITextControl
{
//... ...
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public virtual ListItemCollection Items
{
//... ...
}
//... ...
}
也正因为Items是ListControl唯一的嵌套内容,所以对应表⑥中才可以省略Items标签,直接设置Items的值。
asp:ListItem Value="1" 男 /asp:ListItem !-- 直接设置Items值,就可以了...--
asp:ListItem Value="0" 女 /asp:ListItem
/Items
/asp:DropDownList
③InnerProperty:
复杂的控件通常有多个属性需要持久化在嵌套内容里。这些属性会被装饰上[PersistenceMode(PersistenceMode.InnerProperty)],比如GridView。
[ParseChildren(true)] //在GridView实现代码中没有装饰[ParseChildren(true)],该特性继承自WebControl。
public class GridView : CompositeDataBoundControl, IPostBackContainer, IPostBackEventHandler, ICallbackContainer, ICallbackEventHandler, IPersistedSelector
{
//... ...
[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual DataControlFieldCollection Columns
{
//... ...
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public TableItemStyle EditRowStyle
{
//... ...
}
//... ...
//... ...
}
static Regex _regTrimBeginCarriageReturn = new Regex(@"^(\r\n)+", RegexOptions.Compiled | RegexOptions.Multiline);
//清除源代码后多余的换行符所用的正则表达式
static Regex _regTrimEndCarriageReturn = new Regex(@"(\r\n)+$", RegexOptions.Compiled);
[PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)]
public string Text
{
set
{
this.ViewState["Text"] = value;
}
get
{
object obj = this.ViewState["Text"];
if (null == obj)
{
return string.Empty;
}
return (string)obj;
}
}
protected override void Render(HtmlTextWriter writer)
{
string sourceCode = _regTrimBeginCarriageReturn.Replace(this.Text, string.Empty);
sourceCode = _regTrimEndCarriageReturn.Replace(sourceCode, string.Empty);
sourceCode = HttpUtility.HtmlEncode(sourceCode); //Html编码
sourceCode = sourceCode.Replace(" ", " nbsp;").Replace("\r\n", " br/ ");
writer.Write(sourceCode);
}
}
}
%@ page language="C#" autoeventwireup="true" codebehind="SourceViewTest.aspx.cs"
inherits="CustomServerControlTest.SourceViewTest" %
%@ register assembly="CustomServerControl" namespace="CustomServerControl" tagprefix="csc" %
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
html xmlns="http://www.w3.org/1999/xhtml"
head runat="server"
title /title
/head
body
form id="form1" runat="server"
div
csc:sourceview id="SourceView1" runat="server"
html
head
title Hello SourceView! /title
/head
body
form
h1 SourceView Test /h1
/form
/body
/html
/csc:sourceview
/div
/form
/body
/html
测试截图:
1、嵌套内容是指服务器起始标签与服务器结束标签间的元素集。
2、嵌套内容可以解析成了属性(集合),也可以解析成子控件(集合)。这需要ParseChildrenAttribute告知页分析器,PersistChildrenAttribute告知设计器。
3、简单控件嵌套内容中通常用来持久化最重要的一个属性,复杂控件嵌套内容中通常用来持久化控件中不易于用标签属性表达的复杂属性。需要持久化到嵌套内容的属性需装饰PersistenceModeAttribute。