代码之家  ›  专栏  ›  技术社区  ›  Chris Baxter

在使用自定义system.web.ui.control时,如何使XHTML验证更快乐?

  •  3
  • Chris Baxter  · 技术社区  · 14 年前

    我确信这个问题已经被问过和回答过了,但我还没有找到它……

    我正在创建一个非常简单的自定义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 回复  |  直到 14 年前
        1
  •  2
  •   Rob    14 年前

    我在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; }
        }
    }
    
        2
  •  0
  •   kbrimington    14 年前

    查看ASP.NET Menu 用于序列化子元素集合的示例的控件。此控件使用单个内部属性,称为 <Items> ,其中包含菜单项的集合 您可以模拟 Items 财产 (为清楚起见而有所理解) .

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

    请注意,您可能希望删除 [ParseChildren(true)] [PersistChildren(false)] 如果要将集合序列化为内部属性,则从类定义中。

    如果您希望只支持一个子集合(LA DropDownList ,然后您可以将持久性模式替换为 PersistenceMode.InnerDefaultProperty ,并且能够在不使用包装元素的情况下添加项目。