代码之家  ›  专栏  ›  技术社区  ›  Arthur Chaparyan

自定义ASP.NET容器控件

  •  13
  • Arthur Chaparyan  · 技术社区  · 17 年前

    我一直在尝试创建一个自定义控件,它的工作方式与面板控件完全相同,只是周围有一些分隔符,这样可以创建一个圆角框外观。我找不到一个好的例子来说明如何做到这一点。

    我需要能够将文本和控件放置在控件内,并且在不引用面板的情况下直接访问它(这正是面板控件的工作方式)。

    有人有这方面的例子吗?

    8 回复  |  直到 11 年前
        1
  •  15
  •   FlySwat    17 年前

    有两种方法可以做到这一点。一种是在您的控件上实现InamingContainer,这需要大量的工作。

    另一种方法是从面板继承,并重写renderbegintag和renderdtag方法以添加自定义标记。这很容易。

    public class RoundedCornersPanel : System.Web.UI.WebControls.Panel
    {
        public override RenderBeginTag (HtmlTextWriter writer)
        {
            writer.Write("Your rounded corner opening markup");
            base.RenderBeginTag(writer);
        }
    
        public override RenderEndTag (HtmlTextWriter writer)
        {
            base.RenderEndTag(writer);
            writer.Write("Your rounded corner closing markup");                     
        }
    }
    
        2
  •  13
  •   niaher    13 年前

    这里已经有很多答案了,但是我只是想粘贴这个最基本的实现,而不从panel类继承。接下来是:

    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    [ToolboxData("<{0}:SimpleContainer runat=server></{0}:SimpleContainer>")]
    [ParseChildren(true, "Content")]
    public class SimpleContainer : WebControl, INamingContainer
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(SimpleContainer))]
        [TemplateInstance(TemplateInstance.Single)]
        public virtual ITemplate Content { get; set; }
    
        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            // Do not render anything.
        }
    
        public override void RenderEndTag(HtmlTextWriter writer)
        {
            // Do not render anything.
        }
    
        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write("<div class='container'>");
            this.RenderChildren(output);
            output.Write("</div>");
        }
    
        protected override void OnInit(System.EventArgs e)
        {
            base.OnInit(e);
    
            // Initialize all child controls.
            this.CreateChildControls();
            this.ChildControlsCreated = true;
        }
    
        protected override void CreateChildControls()
        {
            // Remove any controls
            this.Controls.Clear();
    
            // Add all content to a container.
            var container = new Control();
            this.Content.InstantiateIn(container);
    
            // Add container to the control collection.
            this.Controls.Add(container);
        }
    }
    

    然后你可以这样使用它:

    <MyControls:SimpleContainer
        ID="container1"
        runat="server">
        <Content>
            <asp:TextBox
                ID="txtName"
                runat="server" />
    
            <asp:Button
                ID="btnSubmit"
                runat="server"
                Text="Submit" />
        </Content>
    </MyControls:SimpleContainer>
    

    从codebehind,你可以做这样的事情:

    this.btnSubmit.Text = "Click me!";
    this.txtName.Text = "Jack Sparrow";
    
        3
  •  3
  •   baretta    17 年前

    创建继承system.web.ui.control并重写render(htmltextwriter)方法的类。 在此方法中,先渲染周围的开始标记,然后渲染子对象(render children),然后渲染结束标记。

    protected override void Render ( HtmlTextWriter output )
    {
      output.Write ( "<div>" );
      RenderChildren ( output );
      output.Write ( "</div>" );
    }
    

    圆角通常使用CSS和角图像来实现左上角、右上角、左下角和右下角。 可以使用4个嵌套的div作为层,每个div都有一个角图像作为背景图像。

        4
  •  2
  •   Community Mohan Dere    9 年前

    代码项目有一些您可能感兴趣的内容: Panel Curve Container - An ASP.NET Custom Control Nugget . 我相信你可以玩代码,有你想要的行为和外观。

    alt text

        5
  •  2
  •   Hutch    11 年前

    如果不想直接从WebControl继承而不是从面板继承,最简单的方法是用属性修饰类。 [ParseChildren(false)] . 虽然乍一看,这可能表明您不想解析子元素,但是 false 实际上表明,您不希望将子级视为属性。相反,您希望将它们视为控件。

    通过使用此属性,您几乎可以获得开箱即用的所有功能:

    [ToolboxData("<{0}:RoundedBox runat=server></{0}:RoundedBox>")]
    [ParseChildren(false)]
    public class RoundedBox : WebControl, INamingContainer
    {
        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            writer.Write("<div class='roundedbox'>");
        }
    
        public override void RenderEndTag(HtmlTextWriter writer)
        {
            writer.Write("</div>");
        }
    }
    

    这将允许您向页面添加Roundedbox控件,并添加将在DIV中呈现的子级(ASP.NET控件或原始HTML)。

    当然,CSS将被添加到RoundedBox类的正确样式中。

        6
  •  0
  •   Zachary Yates    17 年前

    还有一件事你可以用,那就是 rounded corner extender 在ASP.NET Ajax工具包中。

    我知道这不是你想要的,但你不必编写任何自定义代码。

    希望有帮助!

        7
  •  0
  •   SynBiotik    12 年前

    我研究这个问题是因为我想生成一个2列布局面板。(不完全是,但这是我需要的一个简单的例子。我正在分享我最终使用的解决方案:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace Syn.Test
    {
        [DefaultProperty("Text")]
        [ToolboxData("<{0}:MultiPanel runat=server></{0}:MultiPanel>")]
        [ParseChildren(true)]
        [PersistChildren(false)]
        public class MultiPanel : WebControl, INamingContainer
        {
            public ContentContainer LeftContent { get; set; }
    
            public ContentContainer RightContent { get; set; }
    
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
            }
    
            protected override void Render(HtmlTextWriter output)
            {
                output.AddStyleAttribute("width", "600px");
                output.RenderBeginTag(HtmlTextWriterTag.Div);
    
                output.AddStyleAttribute("float", "left");
                output.AddStyleAttribute("width", "280px");
                output.AddStyleAttribute("padding", "10px");
                output.RenderBeginTag(HtmlTextWriterTag.Div);
                LeftContent.RenderControl(output);
                output.RenderEndTag();
    
                output.AddStyleAttribute("float", "left");
                output.AddStyleAttribute("width", "280px");
                output.AddStyleAttribute("padding", "10px");
                output.RenderBeginTag(HtmlTextWriterTag.Div);
                RightContent.RenderControl(output);
                output.RenderEndTag();
    
                output.RenderEndTag();
             }
        }
    
        [ParseChildren(false)]
        public class ContentContainer : Control, INamingContainer
        {
        }
    }
    

    我仍然存在的问题是,在这个场景中,IntelliSense不起作用,它不会建议使用左右内容标记。

        8
  •  -1
  •   Bruno Shine    17 年前
    public class myCustomPanel : Panel
    {
        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "top_left_corner");
            writer.RenderBeginTag(HtmlTextWriterTag.Div);
                base.RenderBeginTag(writer);
        }
    
        public override void RenderEndTag(HtmlTextWriter writer)
        {
                base.RenderEndTag(writer);
            writer.RenderEndTag();
        }
    
    }
    
    推荐文章