2010-08-28 54 views
3

我相信這個問題已經被提出並回答了;但我還沒有設法找到它...如何在使用Custom System.Web.UI.Control時使XHTML驗證開心?

我正在創建一個非常簡單的自定義System.Web.UI.Control有幾個屬性。我可以在我的ASPX頁面定義以下標籤,一切都開心:

<ns:MyControl runat="server" MyProperty="Value" /> 

但是,如果我想有一個或多個「子」的屬性,就像這樣:

<ns:MyControl runat="server" MyProperty="Value"> 
    <Element AnotherProperty="AnotherValue1" /> 
    <Element AnotherProperty="AnotherValue2" /> 
</ns:MyControl> 

我想不通我需要做什麼才能使XHTML驗證。我一直有

  • 內容是不允許開元素的結束標記之間的「XXX」
  • 元素「XXX」不支持
  • 名稱包含大寫字符,這是不允許

該代碼實際上按預期方式運行,但我還沒有管理找到一個很好的例子,如何正確地做到這一點,所以噸帽子一切都驗證。在實現自定義控制方面,我只是所有的屬性在目前掐滅,看起來是這樣的:

[ParseChildren(true)] 
    [PersistChildren(false)] 
    public class MyControl : Control 
    { 
    public String MyProperty { get; set; } 
    public String Element { get; set; } 
    } 

最終元素是爲了建立元素的集合。任何關於如何正確執行此操作以及如何驗證XHTML的見解都將不勝感激。

在此先感謝。

回答

2

我在2008年寫了一篇關於這方面的博客文章,你可以在這裏找到:Describing ASP.net Control properties declaratively

基本上,實現標記的格式如下:

<Abc:CustomControlUno runat="server" ID="Control1"> 
    <Children> 
     <Abc:Control1Child IntegerProperty="1" StringProperty="Item1" /> 
     <Abc:Control1Child IntegerProperty="2" StringProperty="Item2" /> 
    </Children> 
</Abc:CustomControlUno> 

你會需要下面的代碼:

[ParseChildren(true)] 
[PersistChildren(true)] 
[ToolboxData("<{0}:CustomControlUno runat=server></{0}:CustomControlUno>")] 
public class CustomControlUno : WebControl, INamingContainer 
{ 
    private Control1ChildrenCollection _children; 

    [PersistenceMode(PersistenceMode.InnerProperty)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    public Control1ChildrenCollection Children 
    { 
     get 
     { 
      if (_children == null) 
       _children = new Control1ChildrenCollection(); 
      return _children; 
     } 
    } 
} 

public class Control1ChildrenCollection : List<Control1Child> 
{ 
} 

public class Control1Child 
{ 
    private int integerProperty; 
    private string stringProperty; 

    public string StringProperty 
    { 
     get { return stringProperty; } 
     set { stringProperty = value; } 
    } 

    public int IntegerProperty 
    { 
     get { return integerProperty; } 
     set { integerProperty = value; } 
    } 
} 
0

查看ASP.NET Menu控制序列化子元素集合的示例。此控件使用一個名爲<Items>的內部屬性,其中包含菜單項 的集合。您可以模擬Items屬性(爲了清晰起見,爲了清晰起見)的定義。

[PersistenceMode(PersistenceMode.InnerProperty)] 
public MenuItemCollection Items 
{ 
    get { /* ... */ } 
} 

請注意,你可能會想,如果你打算序列化的集合作爲內部屬性,從你的類定義中移除[ParseChildren(true)][PersistChildren(false)]

如果您希望只支持一個子集合(la DropDownList),那麼您可以換出PersistenceMode.InnerDefaultProperty的持久性模式,並且可以添加項目而不使用包裝元素。

+0

可能請你闡明你爲什麼建議取下解析/兒童堅持屬性?當然,我認爲我應該將Parse視爲真實並堅持爲假,但對於爲什麼應該將其徹底刪除感到好奇?它與PersistenceMode是多餘的嗎? – 2010-08-29 00:27:27

+0

文檔指出「使用元數據屬性ParseChildren(true)標記您的服務器控件指示解析器將服務器控件的標記中包含的元素解釋爲屬性。」在你的例子中,你指定'MyProperty'作爲一個屬性。卸下裝飾可以保護您免受意外的行爲。就這樣。 – kbrimington 2010-08-29 00:46:36