Custom ASP.NET Container Control

血红的双手。 提交于 2019-11-27 14:06:41

问题


I've been trying to create a custom control that works exactly like the Panel control except surrounded by a few divs and such to create a rounded box look. I haven't been able to find a decent example of how to do this.

I need to be able to place text and controls inside the control and access it directly without referencing the panel (exactly the way the Panel control works).

Does anyone have any examples of this?


回答1:


There is two ways to do this. One is to implement INamingContainer on your control, and it takes a lot of effort.

The other way is to inherit from Panel, and override the RenderBeginTag and RenderEndTag methods to add your custom markup. This is easy.

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:


There are already quite a few answers here, but I just wanted to paste the most basic implementation of this without inheriting from Panel class. So here it goes:

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);     } } 

Then you can use it like this:

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

And from codebehind you can do things like this:

this.btnSubmit.Text = "Click me!"; this.txtName.Text = "Jack Sparrow"; 



回答3:


Create a class that inherits System.Web.UI.Control, and overrride the Render ( HtmlTextWriter ) method. In this method, render surrounding start tags, then render the children(RenderChildren), then render end tags.

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

Rounded corners is typically achieved using CSS and corner images for the top left, top right, bottom left and bottom right corners. It could be done using 4 nested divs, acting as layers, each of them having one corner image as their background image.




回答4:


Code project have something that might interest you : Panel Curve Container - An ASP.NET Custom Control Nugget. I am sure you can play with the code and have the behavior and look you want.




回答5:


If you don't want to inherit directly from WebControl instead of from Panel, the easiest way to do this is to decorate the class with the attribute [ParseChildren(false)]. Although at first glance this might suggest that you don't want to parse children, what the false actually indicates is that you don't want the children to be treated as properties. Instead, you want them to be treated as controls.

By using this attribute, you get virtually all of the functionality out of the box:

[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>");     } } 

This will allow you to add RoundedBox controls to your pages, and add children (either asp.net controls or raw html) that will be rendered inside your div.

Of course, css would be added to correctly style the roundedbox class.




回答6:


Just another thing you can use, there's a rounded corner extender in the ASP.Net ajax toolkit.

I know it's not exactly what you asked for, but you don't have to write any custom code.

Hope that helps!




回答7:


I looked at this question because I wanted to produce a 2 column layout panel. (not quite but its a much simpler example of what I needed. I'm sharing the solution that I wound up using:

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     {     } } 

The issue I still have is the intellisense does't work for in this scenario, it won't suggest the Left and Right Content tags.




回答8:


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();     }  } 


来源:https://stackoverflow.com/questions/306288/custom-asp-net-container-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!