一、屬性在頁面及源碼中的表示方式
認真地看看頁面中聲明控件的代碼,你會發現控件屬性在頁面中的表示千變萬化。我們看看下面這些:
<%@ 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>
再看看這些屬性在源碼中的表示:
using CustomServerControlTest;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Web;
using System.Web.Profile;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace ASP
{
[CompilerGlobalScope]
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="Label1" runat="server" Text="Hello Label!"></asp:Label> |
Label1.ID = "Label1";
Label1.Text = "Hello Label!";
|
② |
<asp:Label ID="Label2" runat="server">Hello Label!</asp:Label> |
Label2.ID = "Label2";
Label2.Controls.Add(new LiteralControl("Hello Label!")); |
③ |
<asp:Label ID="Label3" runat="server" Text="Hello Label!" Font-Bold="true" Font-Size="14"></asp:Label> |
Label3.ID = "Label3";
Label3..Text = "Hello Label!";
Label3.Font.Bold = true;
Label3.Font.Size = new FontUnit(new Unit(14.0, UnitType.Point)); |
④ |
<asp:TextBox ID="TextBox1" runat="server">Hello TextBox!</asp:TextBox> |
TextBox1.ID = "TextBox1";
TextBox1.Text = "Hello TextBox!";
|
⑤ |
<asp:Panel ID="Panel1" runat="server">Hello Panel!</asp:Panel> |
Panel1.ID = "Panel1";
Panel1.Controls.Add(new LiteralControl("Hello Panel!")); |
⑥ |
<asp:DropDownList ID="ddlGender" runat="server"> <asp:ListItem Value="1">男</asp:ListItem> <asp:ListItem Value="0">女</asp:ListItem> </asp:DropDownList> |
ddlGender.ID = "ddlGender";
ddlGender.Items.Add( new ListItem{Value = "1",Text = "男"}); ddlGender.Items.Add( new ListItem{Value = "0",Text = "女"}); |
⑦ |
<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> |
Gridview1.ID = "Gridview1";
Gridview1.AutoGenerateColumns = false;
Gridview1.EnableModelValidation = true;
Gridview1.Columns.Add(new BoundField{HeaderText = "HeaderText1"}); Gridview1.Columns.Add(new CheckBoxField{HeaderText = "HeaderText2"}); Gridview1.EditRowStyle .BackColor = Color.Red; |
二、處理嵌套內容
開始之前,先看一下概念,什么是嵌套內容?嵌套內容是指服務器起始標簽與服務器結束標簽間的元素集。
我們對比對應表中②、④發現同樣是嵌套內容,有的被解析成了屬性,有的被解析成了子控件。這種對服務器控件標記中嵌套內容的解析行為是怎么控制的呢?
1、ParseChildrenAttribute登場:
ParseChildrenAttribute:是一個類級別的屬性。使用 ParseChildrenAttribute 類指示頁分析器應如何處理頁上聲明的服務器控件標記中的嵌套內容。
命名空間:System.Web.UI
程序集:System.Web(在 system.web.dll 中)
ParseChildrenAttribute類的構造函數有以下四個重載版本:
名稱 | 說明 |
ParseChildrenAttribute () | 初始化 ParseChildrenAttribute 類的新實例。ChildrenAsProperties 屬性默認為false。 |
ParseChildrenAttribute (Boolean) | 使用 ChildrenAsProperties 屬性初始化 ParseChildrenAttribute 類的新實例,以確定服務器控件標記中的嵌套內容是否被分析為服務器控件的屬性。 |
ParseChildrenAttribute (Type) | 使用 ChildControlType 屬性初始化 ParseChildrenAttribute 類的新實例,以確定服務器控件標記中的嵌套內容哪些元素將被分析為控件。 |
ParseChildrenAttribute (Boolean, String) | 使用 childrenAsProperties 和 defaultProperty 參數初始化 ParseChildrenAttribute 類的新實例。 defaultProperty 用於指定服務器控件標記中的嵌套內容解析成哪個屬性的值。 |
Lable因為裝飾了[ParseChildren(false)]而將其嵌套內容解析為子控件:
[ParseChildren(false)]
public class Label : WebControl, ITextControl
{
//... ...
}
TextBox因為裝飾了[ParseChildren(true, "Text")]而將其嵌套內容解析成屬性值,並賦值給Text屬性:
[ParseChildren(true, "Text")]
public class TextBox : WebControl, IPostBackDataHandler, IEditableTextControl, ITextControl
{
//... ...
}
2、PersistChildrenAttribute登場:
PersistChildrenAttribute:是一個類級別的屬性,使用 PersistChildrenAttribute類指示設計器應如何處理頁上聲明的服務器控件標記中的嵌套內容。
命名空間:System.Web.UI
程序集:System.Web(在 system.web.dll 中)
名稱 | 說明 |
PersistChildrenAttribute(Boolean) | 使用persist屬性初始化PersistChildrenAttribute類的新實例,以告知設計服務器控件標記中的嵌套內容是否仍是控件。 |
PersistChildrenAttribute(Boolean, Boolean) | 用persist屬性和UsesCustomPersistence屬性初始化 PersistChildrenAttribute 類的新實例。 persist屬性指示是否將嵌套內容作為嵌套控件保持,UsesCustomPersistence屬性指示是否使用自定義的保持方法。 |
注:ParseChildrenAttribute和PersistChildrenAttribute常同時出現,ParseChildrenAttribute將對控件標簽內嵌套內容的解析行為告知頁分析器;PersistChildrenAttribute將對控件標簽內嵌套內容的解析行為告知設計器,但兩者構造函數的參數的意義不同。ParseChildrenAttribute的參數為ChildrenAsProperties ,表示是否解析為屬性;PersistChildrenAttribute的參數為persist,表示是否將嵌套內容作為嵌套控件保持。所以控件上如果出現[ParseChildren(false)]就會出現[PersistChildren(true)],反之亦然。
[ParseChildren(false), PersistChildren(true)]
public class Panel : WebControl
{
//... ...
}
3、PersistenceModeAttribute登場:
PersistenceModeAttribute:是一個元素級別的屬性。用於指定控件屬性的保存(持久化)方式,它接受一個枚舉類型參數:PersistenceMode,其枚舉值及意義如下表:
名稱 | 說明 |
Attribute | 指定屬性或事件保持為特性。 |
EncodedInnerDefaultProperty | 指定屬性保存為控件的唯一嵌套內容。當屬性為字符串且是HTML編碼時,只能對該屬性做這種指定。 |
InnerDefaultProperty | 指定屬性保存為控件的唯一嵌套內容。 |
InnerProperty | 指定屬性在 ASP.NET 服務器控件中保持為嵌套標記。 這通常用於復雜對象,它們具有自己的持久性屬性。 |
①EncodedInnerDefaultProperty:
我們上面說到TextBox因為裝飾了[ParseChildren(true, "Text")]而將其嵌套內容解析成Text屬性的屬性值,相應的TextBox的Text屬性也被修飾上了[PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)],使得Text成為TextBox唯一嵌套內容,而且如果嵌套內容中存在標簽格式的文本,解析器頁不會把這些標簽進行進一步解析。
[ParseChildren(true, "Text")]
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唯一嵌套內容。
[ParseChildren(true, "Items")]
public abstract class ListControl : DataBoundControl, IEditableTextControl, ITextControl
{
//... ...
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public virtual ListItemCollection Items
{
//... ...
}
//... ...
}
也正因為Items是ListControl唯一的嵌套內容,所以對應表⑥中才可以省略Items標簽,直接設置Items的值。
<asp:DropDownList ID="ddlGender" runat="server">
<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
{
//... ...
}
//... ...
//... ...
}
三、源代碼視圖控件
實現代碼:
using System.Web.UI;
using System.Text.RegularExpressions;
using System.Web;
namespace CustomServerControl
{
[ParseChildren(true,"Text"),PersistChildren(false)]
public class SourceView:Control
{
//清除源代碼前多余的換行符所用的正則表達式
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(" ", " ").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。