代码之家  ›  专栏  ›  技术社区  ›  tanathos

ASP.NET自定义控件设计时问题

  •  1
  • tanathos  · 技术社区  · 15 年前

    我正在开发一组自定义控件,其中一个是“父级”,任何其他控件都必须添加到此父级的ItemPlate属性中。

    但是在页面中,在设计时,通过智能感知,我可以看到页面级别的其他控件,从理论上讲,我可以将它们添加到任何地方。

    我想模拟asp:table和asp:tablerow的行为,不能直接在asp:table之外添加asp:tablerow…

    有什么方法可以达到这个目的吗? 非常感谢!

    编辑 :我已经部分解决了KP建议,但如果你在评论中看到这不是“真正”的方法(我想)。 没人知道怎么做?:(

    2 回复  |  直到 15 年前
        1
  •  2
  •   KP.    15 年前

    我根据我们的讨论编辑了整个答案。这是一个工作和测试的例子。我们有两个控制器- ParentControl ChildControl . 家长控制 通过IntelliSense可见,其中 儿童控制 仅作为的子级可见 家长控制 如你所愿。为了简单的呈现目的,子对象呈现为li标记并输出其“文本”属性。父控件确保每个子控件在其自身的 RenderContents 事件。

    子控件:

    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace TestControls
    {
        [ToolboxItem(false), Bindable(false)]
        public class ChildControl : WebControl
        {
            protected override void Render(System.Web.UI.HtmlTextWriter writer)
            {
                base.Render(writer);
    
                //render the text property as a list item for example's sake
                writer.RenderBeginTag(HtmlTextWriterTag.Li);
                writer.Write(this.Text);
                writer.RenderEndTag();
            }
    
            [Browsable(true)]
            public string Text { get; set; }
        }
    }
    

    家长控制:

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace TestControls
    {
        [ToolboxData("<{0}:ParentControl runat=\"server\"></{0}:ParentControl>")]
        [DefaultProperty("Children"), ParseChildren(true, "Children")]
        public class ParentControl : WebControl
        {
            private List<ChildControl> _children;
    
            protected override void RenderContents(HtmlTextWriter writer)
            {
                base.RenderContents(writer);
    
                //create a div, and write some sample text
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
                writer.Write("Parent Control. Children:");
    
                //create a ul, and ask each child control to render
                writer.RenderBeginTag(HtmlTextWriterTag.Ul);
    
                foreach (ChildControl child in _children)
                {
                    child.RenderControl(writer);
                }
    
                //close all tags
                writer.RenderEndTag();
                writer.RenderEndTag();
            }
    
            [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
            public virtual List<ChildControl> Children
            {
                get
                {
                    if (_children == null)
                        _children = new List<ChildControl>();
    
                    return _children;
                }
            }
        }
    }
    

    在我的标记中,我通过命名空间注册了控件:

    <%@ Register TagPrefix="test" Namespace="TestControls" %>
    

    然后添加了一些标记:

    <test:ParentControl ID="test" runat="server">
        <test:ChildControl ID="child" Text="Hello World from Child 1" runat="server" />
        <test:ChildControl ID="child2" Text="Hello World from Child 2" runat="server" />
    </test:ParentControl>
    

    在上面的标记中,IntelliSense接受外部父控件,但看不到子控件。一旦光标位于父控件内,IntelliSense将在 儿童控制 按需标记。

    最终输出为:

    父控件。儿童:

    * Hello World from Child 1
    * Hello World from Child 2
    

    还有,这里有一个 good article on how the whole intellisence creation works ,我随后创建了上述内容。

    我希望这有帮助。您仍然需要以您认为适合特定控件的方式处理子控件级别的呈现,但是上面的内容会让您开始工作,并满足工作IntelliSense模型的需要。

        2
  •  0
  •   Dave Swersky    15 年前

    我以前做过,但没有可用的代码。我可以告诉您,我是通过在内置的ASP.NET DataGrid控件上使用Reflector计算出来的。我能够逆向工程“包含的”(“行”)和“容器”(“网格”)之间的关系。您必须使用属性以非常具体的方式将类排列在一起。