4.4.3.2 使用ControlBuilder解析 复杂内容
通过 System.Web.UI.ControlBuilder 类定制页面解析逻辑,可以定制任意类型的标记,而不 像重写AddParseSubObject 方法那样限定子标记必须是子控件,且必须有前缀和runat 属性,下面 直接通过一个例子来说明一下此类的用法。
首先建立两个文件 ScriptItem.cs 和ScriptItemCollection.cs ,分别定义ScriptItem 类和 ScriptItemCollection 类。其中,ScriptItem 类主要存储用户自定义的客户端脚本命令 (JavaScript 块),ScriptItemCollection 可以定义一个集合容器,每个项都是一个ScriptItem 项。与前面讲的集合实现非常类似。这两个类的完整代码如下:
1 .ScriptItem 类
/// <summary>
/// 获得本书更多内容,请看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
/// </summary>
private string _Text;
[DefaultValue("")]
[Editor("System.ComponentModel.Design.MultilineStringEditor,System.Design", typeof (UITypeEditor))]
[PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)]
[NotifyParentProperty(true)]
/// <summary>
/// JavaScript脚本块
/// </summary>
public string Text
{
get
{
return _Text;
}
set
{
_Text = value;
}
}
该类中的Text 就是用于存储用户定义的脚本块;Editor 元数据特性指定在属性窗口中Text 属 性的编辑器是一个下拉块输入编辑器,关于属性编辑器下一节会详细讲解,这里仅知道它的功能即 可。
需要注意的是,在上一节使用AddParsedSubObject 实现页面解析子控件时,要嵌套的三个集合 的子标记:ListItem ,ListItem2 ,ListItem3 都继承了Control 基类,目的是把这些子标记作 为子控件(也就具有了前缀和runat 属性),而这里的ScriptItem 没有继承任何基类,这样就避 免了继承一些基类中的冗余属性和方法。
2 .ScriptItemCollecton 类
/// <summary>
/// 获得本书更多内容,请看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
/// </summary>
[ToolboxItem(false)]
public class ScriptItemCollection : List<ScriptItem>
{
public ScriptItemCollection() : base() { }
public ScriptItemCollection(int capacity) : base(capacity) { }
public ScriptItemCollection(IEnumerable<ScriptItem> collection):base (collection) { }
}
定义这两个类之后,实现我们自己的ControlBuilder 类,可以直接继承该类并实现自己的方法 ,已经预先实现好了的构造器类代码如下所示:
/// <summary>
/// 获得本书更多内容,请看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
/// </summary>
public class ScriptItemBuilder : ControlBuilder
{
public override Type GetChildControlType(string tagName, IDictionary attributes)
{
if (string.Compare(tagName.ToLower(), "scriptitem", false, CultureInfo. InvariantCulture) == 0)
{
return typeof(ScriptItem);
}
return null;
}
public override bool AllowWhitespaceLiterals()
{
return false;
}
}