2008-11-20 6 views
13

Я пытаюсь создать настраиваемый элемент управления, который работает точно так же, как и элемент управления Panel, за исключением окружения несколькими div и т. Д., Чтобы создать округленный вид окна. Я не смог найти достойный пример того, как это сделать.Пользовательское управление контейнером ASP.NET

Мне нужно иметь возможность размещать текст и элементы управления внутри элемента управления и обращаться к нему напрямую, не ссылаясь на панель (точно так же, как работает панель управления).

Есть ли у кого-нибудь примеры этого?

ответ

15

Существует два способа сделать это. Один из них - реализовать INamingContainer под вашим контролем, и это требует больших усилий.

Другой способ - наследовать от Panel и переопределить методы RenderBeginTag и RenderEndTag, чтобы добавить вашу собственную разметку. Это легко.

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

Это, наверное, очень глупый вопрос, но поскольку я не могу разместить этот код в типичном пользовательском элементе управления (.ascx), где бы я его поместил? Я создал класс и разместил его там, но тогда я не знаю, как добавить его на страницу (перетаскивание просто создает ссылку) – 2008-11-20 18:33:29

+0

Задайте вопрос о том, как использовать элементы управления ASP.NET Server, и я могу ответить, Я не могу вписать объяснение в этот маленький блок комментариев. – FlySwat 2008-11-20 18:35:21

3

Создать класс, который наследует System.Web.UI.Control и overrride метод визуализации (HtmlTextWriter). В этом методе визуализируйте окружающие стартовые теги, затем отрисуйте дочерние элементы (RenderChildren), а затем визуализируйте теги конца.

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

закругленные углы, как правило, достигается с помощью CSS и угловые изображения для верхнего левого, верхнего правого, нижнего левого и нижнего правого углов. Это можно сделать, используя 4 вложенных divs, действующих как слои, каждый из которых имеет одно угловое изображение в качестве фонового изображения.

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

} 
0

Просто другая вещь, которую вы можете использовать, есть в Ajax Toolkit ASP.Net в rounded corner extender.

Я знаю, что это не совсем то, о чем вы просили, но вам не нужно писать какой-либо пользовательский код.

Надеюсь, что это поможет!

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> 

И от коде вы можете сделать что-то вроде этого:

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

Я посмотрел на этот вопрос, потому что Я хотел создать панель компоновки с двумя столбцами. (Не совсем, но его гораздо более простой пример того, что мне нужно было я делю решение, которое я ликвидируется с помощью:.

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 does't работу в этом сценарии, он не будет предлагать теги Left и Right Content.

2

Если вы не хотите наследовать непосредственно из WebControl, а не из Panel, самый простой способ сделать это - украсить класс атрибутом [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 на ваших страницах, а также добавить детей (либо элементов управления ASP.NET или raw html), который будет отображаться внутри вашего div.

Конечно, css будет добавлен, чтобы правильно создать класс roundedbox.