第三篇:属性_第二节:控件属性在页面及源码中的表示方式

简介:

一、属性在页面及源码中的表示方式

认真地看看页面中声明控件的代码,你会发现控件属性在页面中的表示千变万化。我们看看下面这些:

<%@ 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(" ", "&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>

测试截图:

clipboard

四、总结

1、嵌套内容是指服务器起始标签与服务器结束标签间的元素集。

2、嵌套内容可以解析成了属性(集合),也可以解析成子控件(集合)。这需要ParseChildrenAttribute告知页分析器,PersistChildrenAttribute告知设计器。

3、简单控件嵌套内容中通常用来持久化最重要的一个属性,复杂控件嵌套内容中通常用来持久化控件中不易于用标签属性表达的复杂属性。需要持久化到嵌套内容的属性需装饰PersistenceModeAttribute。

作者: 韩兆新
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
分类:  [06]ASP.NET相关

本文转自韩兆新博客博客园博客,原文链接:http://www.cnblogs.com/hanzhaoxin/p/4100890.html,如需转载请自行联系原作者
目录
相关文章
|
7月前
|
缓存 JavaScript 前端开发
【Vue】模板语法,插值、指令、过滤器、计算属性及监听属性(内含面试题及毕设等实用案例)上篇
Vue 的模板语法是一种用于在 HTML 中声明式地渲染 Vue 组件的语法。它基于 HTML,并通过特定的模板语法扩展了 HTML。Vue 使用了一种称为 “Mustache” 语法的模板插值来绑定数据到 HTML 元素上。在 Vue 的模板语法中,你可以使用双大括号({{}})将数据绑定到 HTML 元素上,这样数据的值会被动态地替换到相应的位置。 在 Vue 的模板语法中,你可以使用双大括号({{}})将数据绑定到 HTML 元素上,这样数据的值会被动态地替换到相应的位置。
|
8月前
|
前端开发
前端学习笔记202305学习笔记第二十二天-新增修改弹框复用1
前端学习笔记202305学习笔记第二十二天-新增修改弹框复用1
33 0
|
8月前
|
前端开发
前端学习笔记202305学习笔记第二十二天-新增修改弹框复用5
前端学习笔记202305学习笔记第二十二天-新增修改弹框复用5
39 0
|
8月前
|
前端开发
前端学习笔记202305学习笔记第二十二天-新增修改弹框复用3
前端学习笔记202305学习笔记第二十二天-新增修改弹框复用3
39 0
|
9月前
|
JavaScript 前端开发
Dom实操(第二十二课)表格静态创建到动态创建的过程
Dom实操(第二十二课)表格静态创建到动态创建的过程
47 0
|
12月前
|
JSON 小程序 JavaScript
走进小程序【四】小程序自定义Component如何使用,手把手封装一个底部Tabbar栏
走进小程序【四】小程序自定义Component如何使用,手把手封装一个底部Tabbar栏
164 0
走进小程序【四】小程序自定义Component如何使用,手把手封装一个底部Tabbar栏
|
iOS开发
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
126 0
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
|
JavaScript 前端开发
WebApi入门第二章(获取操作页面元素)
WebApi入门第二章(获取操作页面元素)
97 0
WebApi入门第二章(获取操作页面元素)
|
JavaScript 前端开发 小程序
讲述小程序之组件基本内容
讲述小程序之组件基本内容
107 0
讲述小程序之组件基本内容
|
JavaScript 小程序
讲述小程序之组件选择器内容
讲述小程序之组件选择器内容
66 0
讲述小程序之组件选择器内容