62 votes

Comment puis-je utiliser le bouton étiquette avec ASP.NET?

Je voudrais utiliser la plus récente, <button> balise dans un ASP.NET site web, qui, entre autres choses, permet CSS, texte et l'incorporation d'un graphique à l'intérieur du bouton. L'asp:Bouton de contrôle de rendu sous la forme d' <input type="button">, est-il possible de faire une préexistant de contrôle de rendu en <button>?

De ce que j'ai lu il y a une incompatibilité avec IE l'affichage du bouton de balisage au lieu de la valeur de l'attribut lorsque le bouton est situé à l'intérieur d'un <form>, mais dans ASP.NET il sera à l'aide de l'événement onclick de feu __doPostBack de toute façon, donc je ne pense pas que ce serait un problème.

Existe-il des raisons pourquoi je ne devrais pas l'utiliser? Si non, comment vous y prendriez-vous de le soutenir avec de l'asp:Button, ou d'un nouveau serveur de contrôle sur la base d'? Je préfère ne pas écrire mon propre serveur de contrôle si cela peut être évité.


Au premier abord, l' <button runat="server"> solution a fonctionné, mais j'ai immédiatement couru dans une situation où elle doit avoir une propriété CommandName, qui le contrôle HtmlButton n'ont pas. On dirait que je vais avoir besoin de créer un contrôle hérité de Bouton après tout.

Que dois-je faire pour remplacer la méthode render et faire rendre ce que je veux?


Mise à JOUR

DanHerbert réponse m'a fait intéressés à trouver une solution à cela de nouveau, j'ai donc passé un peu plus de temps à travailler sur elle.

Tout d'abord, il y a beaucoup de moyen plus facile de surcharger le TagName:

public ModernButton() : base(HtmlTextWriterTag.Button)
{
}

Le problème avec Dan la solution, comme il se est le innerhtml de la balise est placée dans la valeur de la propriété, ce qui provoque une erreur de validation sur la publication. Un problème connexe est, même si vous rendre la valeur de la propriété correctement, c'est à dire de braindead de mise en œuvre de l' <button> balise affiche le innerhtml au lieu de la valeur de toute façon. Ainsi, toute mise en œuvre de cette doit remplacer le AddAttributesToRender méthode afin d'afficher correctement la valeur de la propriété, et fournissent également une sorte de solution de contournement pour IE, donc il n'est pas complètement bousiller la publication.

Le problème IE peut être insurmontable si vous voulez profiter de la CommandName/CommandArgument les propriétés d'un contrôle lié aux données. J'espère que quelqu'un peut proposer une solution de contournement pour ce.

J'ai fait des progrès sur le rendu:

ModernButton.cs

Cela rend un bon html <button> avec la valeur correcte, mais il ne fonctionne pas avec le ASP.Net Publication du système. J'ai écrit certains de ce que j'ai besoin de fournir à l' Command événement, mais il n'a pas d'incendie.

Lors de l'inspection ce bouton side-by-side avec un régulier asp:Button, ils regardent la même chose d'autres que les différences que j'ai besoin. Donc je ne suis pas sûr de savoir comment ASP.Net est de câblage de l' Command événement dans ce cas.

Un problème supplémentaire est, imbriqués les contrôles serveur ne sont pas rendus (comme vous pouvez le voir avec la ParseChildren(faux) attribut). Il est assez facile d'injecter littérale du texte html dans le contrôle en cours de rendu, mais comment voulez-vous permettre de soutien pour imbriqués les contrôles serveur?

43voto

Philippe Points 1633

Bien que vous dire que l'aide de la touche [runat="server"] n'est pas une bonne solution, il est important de le mentionner - beaucoup de .NET programmeurs ont peur d'utiliser le "natif" des balises HTML...

Au lieu de:

<asp:button id="btnSubmit" runat="server" cssclass="myButton" 
    onclick="btnSubmit_Click" text="Hello" />

Écrire:

<button id="btnSubmit" runat="server" class="myButton" 
    onserverclick="btnSubmit_Click">Hello</button>

Généralement, cela fonctionne parfaitement bien et tout le monde est heureux dans mon équipe.

29voto

Dan Herbert Points 38336

Je suis tombé sur votre question recherchent exactement la même chose. J'ai fini par utiliser un Réflecteur pour comprendre comment l'ASP.NET Button de contrôle est effectivement rendu. Il s'avère être très facile à changer.

Il a vraiment tout se résume à la redéfinition de l' TagName et TagKey propriétés de l' Button classe. Après vous avez fait cela, vous avez juste besoin de assurez-vous de rendre le contenu du bouton manuellement depuis l'origine Button classe jamais eu de contenu pour le rendu et le contrôle de la rendre un texte-bouton de moins si vous ne le rend pas le contenu.

Mise à jour:

Il est possible de faire quelques petites modifications pour le Bouton de contrôle à travers l'héritage et encore le travail assez bien. Cette solution élimine la nécessité de mettre en œuvre vos propres gestionnaires d'événements pour OnCommand (bien que si vous voulez apprendre comment faire ce que je peux vous montrer comment cela est géré). Il résout également le problème de la soumission d'une valeur de balisage, sauf pour IE probablement. Je ne suis toujours pas sûr de la façon de fix IE pauvres de la mise en œuvre de la balise Button. Que peut juste être un véritable limitation technique qui est impossible à contourner...

[ParseChildren(false)]
[PersistChildren(true)]
public class ModernButton : Button
{
    protected override string TagName
    {
        get { return "button"; }
    }

    protected override HtmlTextWriterTag TagKey
    {
        get { return HtmlTextWriterTag.Button; }
    }

    // Create a new implementation of the Text property which
    // will be ignored by the parent class, giving us the freedom
    // to use this property as we please.
    public new string Text
    {
        get { return ViewState["NewText"] as string; }
        set { ViewState["NewText"] = HttpUtility.HtmlDecode(value); }
    }

    protected override void OnPreRender(System.EventArgs e)
    {
        base.OnPreRender(e);
        // I wasn't sure what the best way to handle 'Text' would
        // be. Text is treated as another control which gets added
        // to the end of the button's control collection in this 
        //implementation
        LiteralControl lc = new LiteralControl(this.Text);
        Controls.Add(lc);

        // Add a value for base.Text for the parent class
        // If the following line is omitted, the 'value' 
        // attribute will be blank upon rendering
        base.Text = UniqueID;
    }

    protected override void RenderContents(HtmlTextWriter writer)
    {
        RenderChildren(writer);
    }
}

Pour utiliser cette commande, vous avez quelques options. On est à la place de contrôles directement dans l'ASP balisage.

<uc:ModernButton runat="server" 
        ID="btnLogin" 
        OnClick="btnLogin_Click" 
        Text="Purplemonkeydishwasher">
    <img src="../someUrl/img.gif" alt="img" />
    <asp:Label ID="Label1" runat="server" Text="Login" />
</uc:ModernButton>

Vous pouvez également ajouter les commandes pour le contrôle de la collecte de bouton dans votre code-behind.

// This code probably won't work too well "as is"
// since there is nothing being defined about these
// controls, but you get the idea.
btnLogin.Controls.Add(new Label());
btnLogin.Controls.Add(new Table());

Je ne sais pas comment bien une combinaison des deux options fonctionne comme je n'ai pas testé.

Le seul inconvénient de ce droit de contrôle est maintenant que je ne pense pas qu'il se souviendra de vos contrôles dans les Publications. Je n'ai pas testé cette sorte qu'il peut déjà travailler, mais je doute qu'il fait. Vous aurez besoin d'ajouter un peu de ViewState code de gestion pour les sous-contrôles qui doivent être effectués à travers les Publications, mais je crois que ce n'est probablement pas un problème pour vous. L'ajout de ViewState de soutien ne devrait pas être très difficile à faire, mais si nécessaire, qui peut facilement être ajouté.

6voto

Steven Robbins Points 18791

Vous pourriez faire un nouveau contrôle, héritant de Bouton, et de remplacer la méthode render, ou utiliser un .navigateur de fichiers pour remplacer tous les Boutons du site, de la même façon le CSS Friendly œuvres de trucs pour le contrôle TreeView etc.

6voto

Wayne Points 12304

Vous pouvez utiliser le Bouton.UseSubmitBehavior propriété comme expliqué dans cet article sur le rendu d'une ASP.NET Bouton de contrôle de la forme d'un bouton.


EDIT: Désolé.. c'est ce que je reçois pour l'écrémage des questions sur ma pause déjeuner. Existe-il des raisons pourquoi vous ne vous contentez pas d'utiliser un bouton <runat="server"> balise ou un HtmlButton?

2voto

Tsvetomir Tsonev Points 42030

Je voudrais aller avec un LinkButton et de style avec CSS appropriée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X