Question

J'ai essayé de créer un contrôle personnalisé qui fonctionne exactement comme le contrôle Panel, sauf qu'il est entouré de quelques divs et permet de créer un aspect de boîte arrondie. Je n'ai pas été en mesure de trouver un exemple décent de la façon de procéder.

Je dois pouvoir placer du texte et des commandes à l'intérieur du contrôle et y accéder directement sans faire référence au panneau (exactement comme le contrôle le panneau).

Quelqu'un at-il des exemples de cela?

Était-ce utile?

La solution

Il y a deux façons de faire cela. L’une consiste à implémenter INamingContainer sur votre commande, et cela demande beaucoup d’efforts.

L'autre méthode consiste à hériter de Panel et à remplacer les méthodes RenderBeginTag et RenderEndTag pour ajouter votre balisage personnalisé. C’est facile.

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

Autres conseils

Il y a déjà pas mal de réponses ici, mais je voulais simplement coller l'implémentation la plus basique de cela sans hériter de la classe Panel. Alors voilà:

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

Ensuite, vous pouvez l'utiliser comme ceci:

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

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

Et à partir du code ci-dessous, vous pouvez faire des choses comme ceci:

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

Créez une classe qui hérite de System.Web.UI.Control et substituez la méthode Render (HtmlTextWriter). Dans cette méthode, restituez les balises de début environnantes, puis les enfants (RenderChildren), puis les balises de fin.

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

Les coins arrondis sont généralement obtenus à l'aide de CSS et d'images de coin pour les coins supérieur gauche, supérieur droit, inférieur gauche et inférieur droit. Cela pourrait être fait en utilisant 4 divs imbriqués, agissant en tant que calques, chacun d'eux ayant une image de coin comme image de fond.

Code project a quelque chose qui pourrait vous intéresser: Conteneur de courbe de panneau - Un ASP Nugget de contrôle personnalisé .NET . Je suis sûr que vous pouvez jouer avec le code, avoir le comportement et le look que vous souhaitez.

alt text

Si vous ne souhaitez pas hériter directement de WebControl au lieu de Panel, le moyen le plus simple consiste à décorer la classe avec l'attribut [ParseChildren (false)] . Bien qu'à première vue, cela puisse suggérer de ne pas analyser les enfants, ce que false indique en réalité, c'est que vous ne souhaitez pas que les enfants soient traités comme des propriétés. Au lieu de cela, vous voulez qu’ils soient traités comme des contrôles.

En utilisant cet attribut, vous obtenez pratiquement toutes les fonctionnalités prêtes à l'emploi:

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

Cela vous permettra d’ajouter des contrôles RoundedBox à vos pages et d’ajouter des enfants (soit des contrôles asp.net, soit du code HTML brut) qui seront rendus dans votre div.

Bien sûr, des CSS seraient ajoutés pour styliser correctement la classe roundedbox.

Une autre chose que vous pouvez utiliser est un extension de coin arrondi dans la boîte à outils ASP.Net ajax.

Je sais que ce n'est pas exactement ce que vous avez demandé, mais vous n'avez pas à écrire de code personnalisé.

J'espère que ça aide!

J'ai examiné cette question parce que je voulais créer un panneau de présentation à 2 colonnes. (pas tout à fait, mais c’est un exemple beaucoup plus simple de ce dont j’avais besoin. Je partage la solution que j’ai utilisée:

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

Le problème que j’ai toujours, c’est que intellisense ne fonctionne pas dans ce scénario, il ne suggère pas les balises Left et Right Content.

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

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top