日期:2014-05-18  浏览次数:20451 次

开发模板化自定义控件(templated custom control)时遇到的难题
我在开发一个模板化的自定义控件时,希望能限制模板内的自定义子控件只允许被放置于模板内,而不允许直接在页面中使用。这种效果可类比到gridview的boundfield:

<asp:GridView   ID= "GridView1 "   runat= "server ">
    <Columns>
        <asp:BoundField   />
    </Columns>
</asp:GridView>

<asp:boundfield> 是只允许被声明于 <columns> 标记内,而不允许直接写在页面中。

请问这样的效果该如何实现呢?我在网上找了两天都没找到答案,希望csdn的高人出手相助~

------解决方案--------------------
<asp:BoundField /> 不是一个子控件,你可以查看其基类,并没有沿 System.Web.UI.Control 继承下来

这种叫做【复合属性】,通常需要实现 IStateManager
------解决方案--------------------

复合控件定义复杂类型的属性:
ref:http://www.cnblogs.com/CHONGCHONG2008/archive/2007/05/23/757170.html

1.3 内部默认属性的实现
内部默认属性持久性通常用于持久保存某个控件的集合属性。如:
<asp:ListBox id= "listbox1 " Width= "100px " runat= "server ">
<asp:ListItem> Item 1 </asp:ListItem>
<asp:ListItem> Item 2 </asp:ListItem>
<asp:ListItem> Item 3 </asp:ListItem>
</asp:ListBox>

当某个控件有内部默认属性的时候,控件标签中的内容就只跟该书性对应。页面解析器不允许控件标签中有任何其他属性。内部默认属性的名称并不是在控件标签内部制定的。
为了实现内部默认属性的持久性,必须用ParseChildrenAttribute attribute的变种来标记控件,该attribute的第二个参数是内部默认属性的名称。


1 [
2 PersistChildren(true, "默认属性名 ")
3 ]
4 public class MyControl : WebControl{.}


而且为了在设计器中正确的持久保存某个内部默认属性,必须用PersistenceMode(PersistenceMode.InnerDefaultProperty)来标记该属性。如:


1 [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
2 public virtual ListItemCollection Items{}