Пользовательский элемент управления контейнером ASP.NET - PullRequest
13 голосов
/ 20 ноября 2008

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

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

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

Ответы [ 8 ]

15 голосов
/ 20 ноября 2008

Есть два способа сделать это. Одним из них является реализация 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");                     
    }
}
13 голосов
/ 22 февраля 2012

Здесь уже довольно много ответов, но я просто хотел вставить самую базовую реализацию этого, не наследуя от класса 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";
3 голосов
/ 20 ноября 2008

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

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

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

2 голосов
/ 03 декабря 2014

Если вы не хотите наследовать напрямую от 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 или необработанный HTML), которые будут отображаться внутри вашего div.

Конечно, CSS будет добавлен, чтобы правильно оформить класс закругленной коробки.

2 голосов
/ 20 ноября 2008

В проекте кода есть кое-что, что может вас заинтересовать: Контейнер кривой панели - слепок настраиваемого элемента управления ASP.NET . Я уверен, что вы можете играть с кодом и вести себя так, как вам хочется.

alt text

0 голосов
/ 10 декабря 2013

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

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 не работает в этом сценарии, он не будет предлагать левый и правый теги содержимого.

0 голосов
/ 20 ноября 2008

Еще одна вещь, которую вы можете использовать, это расширитель закругленных углов в наборе инструментов ASP.Net ajax.

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

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

0 голосов
/ 20 ноября 2008
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();
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...