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

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

<%@ 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>

测试截图:

四、总结

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

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

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

转载于:https://www.cnblogs.com/hanzhaoxin/p/4100890.html

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

  1. RCNN学习笔记——第三篇: 实现FRCNN网络训练、评价与预测(附全部源码)

    RCNN学习笔记--第三篇: 实现FRCNN网络训练.评价与预测(附全部源码) 本文是个人根据B站大佬Bubbliiiing的FRCNN系列视频同步完成FRCNN训练,记录心得和遇见的问题. 关于RC ...

  2. [共享]一个文件上传的控件,绝对是精品源码

    [共享]一个文件上传的控件,绝对是精品源码 前段时候在www.codeproject.com上看到一个文件上传的控件,觉得很好,共享给园子里的朋友. 原文链接:http://www.codeproje ...

  3. android查看控件的xml属性,006 Android XML 控件属性设置技巧汇总

    1.textview 组件文本实现替换(快速实现字符资源的调用) android 应用资源位置在 project(工程名)--->app--->res--->values 在stri ...

  4. android控件常用的属性,android?常用的控件属性

    1.Android RelativeLayout 属性 // 相对于给定ID控件 android:layout_above 将该控件的底部置于给定ID的控件之上; android:layout_bel ...

  5. mac下dashboard小控件开发实例(附源码)

    1.背景          用mac的用户都应该知道,mac有一个很好的功能,就是dashboard小控件的功能,按下F12键就可以自由切换.博主最近在背GRE单词,就尝试这开发了一个背单词的dash ...

  6. PowerBuilder 9日历控件展示,下载(附带源码)

    下载地址:https://download.csdn.net/download/weixin_37914760/11444539 1.pb9日历控件,支持多个日期选择

  7. mybatisplus修改单个属性_第二节 官封弼马温——类的属性

    <西游记>第2集 官封弼马温 美猴王战胜了混世魔王,花果山上喜气洋洋,小猴们每日操演武艺,十分快乐.悟空闯入东海龙宫,向龙王索取镇海神针--如意金箍棒.这棒虽重一万三千五百斤,却大可撑天着 ...

  8. 自然语言处理NLP-100例 | 第三篇:骚扰短信识别 MultinomialNB实现(内附源码)

    大家好,我是K同学啊~ 每当手机短信想起,第一反应就是****,奈何是一条又一条的骚然短信.目前对于垃圾短信的处理方法多是进行识别关键字进而拦截.这种方法准确率还是蛮高的基本没有错误,但是拦截面就很有 ...

  9. java 日历控件_java swing 日历控件怎么实现 最好是源码

    展开全部 源代码: e69da5e887aa3231313335323631343130323136353331333330363864//DatePicker.java package com.kx ...

最新文章

  1. 【ZT】我家宝宝不会哭----分享在美国养孩子的妈妈经(必看)
  2. 深入理解openstack网络架构(2)----Basic Use Cases
  3. 三、CSS重要的盒子模型知识总结(中篇)
  4. centos6.5虚拟机安装后,没有iptables配置文件
  5. Hadoop 07_MapReduce运行的三种方式
  6. VCSA 6.7 U2无DNS部署 VCSA 7正式版无DNS部署
  7. smokeping主从同步报错
  8. python安装依赖比较慢的解决方法
  9. PAT 乙级 1017. A除以B (20) Java版
  10. 如何用shell脚本读取配置文件
  11. Flask渲染Jinja2模板
  12. php 生成多个水印,php 生成水印的完整代码
  13. 西门子1200控制V90伺服,西门子1200通过PN通讯控制 V90伺服,程序控制采用FB285功能块
  14. php坏处,cpu超频有什么坏处
  15. Spring Boot 自定义注解支持EL表达式(基于 MethodBasedEvaluationContext 实现)
  16. apache common base64编码
  17. 启用nat模式 路由模式_如何在HTML电子邮件中启用暗模式:您需要了解的一切。...
  18. MAX17043锂电池电量测量芯片C51驱动
  19. 年入200万的华人程序员,过了30岁就成傻逼了?
  20. Java反序列化(一) - Java反射机制

热门文章

  1. Seam开发环境的搭建
  2. 下载天方听书网的媒体
  3. MMDetection库部署和训练
  4. 【Python学习系列十】Python机器学习库scikit-learn实现Decision Trees案例
  5. vc关于dialog绘图闪屏和多层覆盖的处理方法
  6. 六个月学php,修学六个月心得体会
  7. Rest 微服务工程搭建01——微服务提供者Module模块
  8. Understand Event-Driven Software Architecture
  9. DATE_FORMAT() 函数||DATE_SUB() 函数
  10. RT-Thread的I/O设备模块及其驱动实现步骤