Question

Résumé

Salut tout le monde,
OK, plus loin dans mes aventures avec des commandes personnalisées...

En résumé, voici que j’ai découvert trois « classes » principales de contrôles personnalisés.N'hésitez pas à me corriger si quelque chose ne va pas !

  1. Contrôles utilisateur - Qui héritent de Contrôle utilisateur et sont contenus dans un ASCX déposer.Ceux-ci sont assez limités dans ce qu'ils peuvent faire, mais constituent un moyen rapide et léger d'obtenir des points communs en matière d'interface utilisateur avec le support des concepteurs.
  2. Contrôles composites personnalisés - Ce sont des contrôles qui héritent de Contrôle Web où vous ajoutez des contrôles préexistants au contrôle dans le Créer des contrôles enfants méthode.Cela offre une grande flexibilité, mais manque de prise en charge par les concepteurs sans codage supplémentaire.Ils sont cependant hautement portables puisqu’ils peuvent être compilés dans une DLL.
  3. Contrôles rendus personnalisés - Semblables aux contrôles composites personnalisés, ceux-ci sont ajoutés à un projet de bibliothèque de contrôles Web.Le rendu du contrôle est entièrement contrôlé par le programmeur en remplaçant le Rendre méthode.

Mes pensées..

OK, donc en jouant avec des composites personnalisés, j'ai trouvé ce qui suit :

  • Vous avez peu ou pas de contrôle sur la sortie HTML, ce qui rend le "débogage" difficile.
  • Le Créer des contrôles enfants (et les méthodes suivantes) peuvent être très occupés avec Controls.Add(myControl) partout.
  • J'ai trouvé que le rendu des tableaux (que ce soit pour la mise en page ou le contenu) était considérablement gênant.

Questions)..

Donc, j'avoue, je suis nouveau dans ce domaine, donc je pourrais être très éloigné de certains de mes points notés ci-dessus.

  • Utilisez-vous des composites ?
  • Avez-vous des astuces pour contrôler la sortie HTML ?
  • Dites-vous simplement « au diable » et continuez et créez un contrôle de rendu personnalisé ?

C'est quelque chose que j'ai envie d'être vraiment ferme dans mon esprit puisque je sais à quel point bien le développement de contrôles peut réduire le temps de développement global.

J'attends vos réponses avec impatience ^_^

Était-ce utile?

La solution

Je dis d'aller de l'avant avec le contrôle rendu personnalisé.Je trouve que dans la plupart des cas, le composite peut être plus facile à réaliser et à utiliser dans un UserControl, mais au-delà de cela, vous auriez besoin d'un degré de contrôle plus fin (jeu de mots involontaire) pour mériter votre propre stratégie de rendu.

Il peut y avoir des contrôles suffisamment simples pour mériter un composite (par exemple, une zone de texte combinée avec un sélecteur de date basé sur javascript/dhtml, par exemple), mais au-delà de cet exemple, il semble que les contrôles rendus personnalisés soient la voie à suivre.

Autres conseils

Voici une autre méthode d'extension que j'utilise pour le rendu personnalisé :

 public static void WriteControls
        (this HtmlTextWriter o, string format, params object[] args)
 { 
    const string delimiter = "<2E01A260-BD39-47d0-8C5E-0DF814FDF9DC>";
    var controls  = new Dictionary<string,Control>();

    for(int i =0; i < args.Length; ++i)
    { 
       var c = args[i] as Control; 
       if (c==null) continue;
       var guid = Guid.NewGuid().ToString();
       controls[guid] = c;
       args[i] = delimiter+guid+delimiter;
    }

    var _strings = string.Format(format, args)
                         .Split(new string[]{delimiter},
                                StringSplitOptions.None);
    foreach(var s in _strings)
    { 
       if (controls.ContainsKey(s)) 
           controls[s].RenderControl(o);
       else 
           o.Write(s);
    }
}

Ensuite, pour restituer un composite personnalisé dans la méthode RenderContents(), j'écris ceci :

protected override void RenderContents(HtmlTextWriter o)
{ 
    o.WriteControls
         (@"<table>
               <tr>
                    <td>{0}</td>
                    <td>{1}</td>
               </tr>
             </table>"
            ,Text
            ,control1);
 }

Rob, tu as raison.L’approche que j’ai mentionnée est en quelque sorte hybride.L'avantage d'avoir des fichiers ascx est que sur chaque projet que j'ai vu, les concepteurs se sentiraient plus à l'aise avec l'édition du balisage réel et avec l'ascx, vous et un concepteur pouvez travailler séparément.Si vous ne prévoyez pas de modifications CSS/balisage/conception réelles sur les contrôles eux-mêmes plus tard, vous pouvez opter pour un contrôle rendu personnalisé.Comme je l'ai dit, mon approche n'est pertinente que pour des scénarios plus compliqués (et c'est probablement là que vous avez besoin d'un concepteur :))

J'utilise souvent des contrôles composites.Au lieu de remplacer Render ou RenderContents, attribuez simplement à chaque contrôle une CssClass et utilisez des feuilles de style.Pour plusieurs Controls.Add, j'utilise une méthode d'extension :

//Controls.Add(c1, c2, c3)
static void Add(this ControlCollection coll, params Control[] controls)
 { foreach(Control control in controls) coll.Add(control);
 }

Pour un rendu rapide et sale, j'utilise quelque chose comme ceci :

writer.Render(@"<table>
                   <tr><td>{0}</td></tr>
                   <tr>
                       <td>", Text);
control1.RenderControl(writer);
writer.Render("</td></tr></table>");

Pour initialiser les propriétés du contrôle, j'utilise la syntaxe d'initialisation de propriété :

childControl = new Control {  ID="Foo"
                            , CssClass="class1"
                            , CausesValidation=true;
                           };

L’utilisation de contrôles composites personnalisés est utile dans une situation où vous disposez d’une grande application Web et souhaitez réutiliser de gros morceaux à de nombreux endroits.Ensuite, vous ajouteriez uniquement les contrôles enfants de ceux que vous développez au lieu de vous répéter.Sur un grand projet sur lequel j'ai travaillé récemment, ce que nous avons fait est le suivant :

  • Chaque contrôle composite possède un conteneur.Utilisé comme emballage pour tout ce qui se trouve à l'intérieur du contrôle.
  • Chaque contrôle composite possède un modèle.Un fichier ascx (sans la directive <%Control%>) qui contient uniquement le balisage du modèle.
  • Le conteneur (étant un contrôle en soi) est initialisé à partir du modèle.
  • Le conteneur expose les propriétés de tous les autres contrôles du modèle.
  • Vous utilisez uniquement this.Controls.Add([the_container]) dans votre contrôle composite.

En fait, vous avez besoin d'une classe de base qui se chargerait d'initialiser un conteneur avec le modèle spécifié et qui lancerait également des exceptions lorsqu'un contrôle n'est pas trouvé dans le modèle.Bien sûr, cela risque d’être excessif dans une petite application.Si vous n'avez pas de code et de balisage réutilisés et que vous souhaitez uniquement écrire des contrôles simples, il est préférable d'utiliser les contrôles utilisateur.

Vous pourrez peut-être utiliser cette technique pour faciliter la conception :

http://aspadvice.com/blogs/ssmith/archive/2007/10/19/Render-User-Control-as-String-Template.aspx

Fondamentalement, vous créez une instance d'un contrôle utilisateur au moment de l'exécution à l'aide de la méthode LoadControl, puis lui remettez un statebag quelconque, puis l'attachez à l'arborescence de contrôle.Ainsi, votre contrôle composite fonctionnerait en fait comme davantage un contrôleur et le fichier .ascx serait comme une vue.

Cela vous éviterait d’avoir à instancier l’intégralité de l’arborescence de contrôle et à styliser le contrôle en C# !

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