Pregunta

Resumen

Hola a todos,
Bien, más adelante en mis aventuras con controles personalizados...

En resumen, he aprendido sobre tres "clases" principales de controles personalizados.¡No dudes en corregirme si algo de esto está mal!

  1. Controles de usuario - Que heredan de Control de usuario y están contenidos dentro de un ASCX archivo.Estos son bastante limitados en lo que pueden hacer, pero son una forma rápida y sencilla de obtener algunos puntos en común en la interfaz de usuario con el soporte del diseñador.
  2. Controles compuestos personalizados - Son controles que heredan de Control web donde agrega controles preexistentes al control dentro del Crear controles infantiles método.Esto proporciona una gran flexibilidad, pero falta de soporte del diseñador sin codificación adicional.Sin embargo, son muy portátiles ya que se pueden compilar en una DLL.
  3. Controles renderizados personalizados - De manera similar a los controles compuestos personalizados, estos se agregan a un proyecto de biblioteca de controles web.La representación del control está completamente controlada por el programador anulando el Prestar método.

Mis pensamientos..

Bien, mientras jugaba con composiciones personalizadas, encontré lo siguiente:

  • Tiene poco o ningún control sobre la salida HTML, lo que dificulta la "depuración".
  • El Crear controles infantiles (y métodos posteriores) pueden estar muy ocupados con Controles.Agregar(miControl) en todos lados.
  • Encontré que representar tablas (ya sea para diseño o contenido) es considerablemente incómodo.

Las preguntas)..

Entonces, lo admito, soy nuevo en esto, por lo que podría estar muy equivocado con algunos de los puntos mencionados anteriormente.

  • ¿Usas compuestos?
  • ¿Tiene algún truco interesante para controlar la salida HTML?
  • ¿Simplemente dice "al diablo con esto" y continúa y crea un control renderizado personalizado?

Es algo que me gustaría tener muy firme en mi mente ya que sé cuánto bien El desarrollo del control puede reducir el tiempo de desarrollo general.

Espero vuestras respuestas ^_^

¿Fue útil?

Solución

Yo digo que siga adelante con el control renderizado personalizado.Encuentro que en la mayoría de los casos la composición puede ser más fácil de hacer y usar en un UserControl, pero cualquier cosa más allá de eso necesitaría tener un mayor grado de control (juego de palabras no intencionado) para merecer su propia estrategia de renderizado.

Tal vez haya controles que sean lo suficientemente simples como para merecer una composición (por ejemplo, un cuadro de texto combinado con un selector de fecha basado en javascript/dhtml, por ejemplo), pero más allá de ese ejemplo, parece que los controles renderizados personalizados son el camino a seguir.

Otros consejos

Aquí hay otro método de extensión que uso para la representación personalizada:

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

Luego, para renderizar un compuesto personalizado en el método RenderContents() escribo esto:

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

Rob, tienes razón.El enfoque que mencioné es una especie de híbrido.La ventaja de tener archivos ascx es que en cada proyecto que he visto, los diseñadores se sentirían más cómodos editando el marcado real y con el ascx usted y el diseñador pueden trabajar por separado.Si no planea cambios reales de CSS/marcado/diseño en los controles más adelante, puede optar por un control renderizado personalizado.Como dije, mi enfoque solo es relevante para escenarios más complicados (y probablemente aquí sea donde necesites un diseñador :))

A menudo uso controles compuestos.En lugar de anular Render o RenderContents, simplemente asigne a cada Control una CssClass y use hojas de estilo.Para múltiples Controls.Add, utilizo un método de extensión:

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

Para un renderizado rápido y sucio, uso algo como esto:

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

Para inicializar las propiedades de control, utilizo la sintaxis del inicializador de propiedades:

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

El uso de controles compuestos personalizados tiene sentido en una situación en la que tiene una aplicación web grande y desea reutilizar fragmentos grandes en muchos lugares.Entonces solo agregarías controles secundarios de los que estás desarrollando en lugar de repetirlos.En un proyecto grande en el que trabajé recientemente, lo que hicimos fue lo siguiente:

  • Cada control compuesto tiene un contenedor.Se utiliza como envoltorio para todo lo que se encuentra dentro del control.
  • Cada control compuesto tiene una plantilla.Un archivo ascx (sin la directiva <%Control%>) que solo contiene el marcado de la plantilla.
  • El contenedor (que es un control en sí mismo) se inicializa desde la plantilla.
  • El contenedor expone propiedades para todos los demás controles de la plantilla.
  • Solo usa this.Controls.Add([the_container]) en su control compuesto.

De hecho, necesita una clase base que se encargue de inicializar un contenedor con la plantilla especificada y también arroje excepciones cuando no se encuentre un control en la plantilla.Por supuesto, esto probablemente sea excesivo en una aplicación pequeña.Si no ha reutilizado código ni marcado y solo desea escribir controles simples, es mejor que utilice controles de usuario.

Es posible que pueda utilizar esta técnica para facilitar el tiempo de diseño:

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

Básicamente, crea una instancia de un control de usuario en tiempo de ejecución utilizando el método LoadControl, luego le entrega una bolsa de estado de algún tipo y luego la adjunta al árbol de control.Entonces su control compuesto en realidad funcionaría más como un controlador, y el archivo .ascx sería como una vista.

¡Esto le ahorraría la molestia de tener que crear una instancia de todo el árbol de control y diseñar el control en C#!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top