personalizados - manejo de usuarios c#
Controles personalizados de ASP.NET-Composites (6)
Resumen
Hola a todos,
OK, más adelante en mis aventuras con controles personalizados ...
En resumen, aquí está que he aprendido de tres "clases" principales de controles personalizados. ¡Por favor, siéntete libre de corregirme si algo de esto está mal!
- UserControls - Que heredan de UserControl y están contenidos dentro de un archivo ASCX . Estos son bastante limitados en lo que pueden hacer, pero son una manera rápida y ligera de obtener algo de UI en común con el apoyo del diseñador.
- Controles compuestos personalizados : estos son controles que heredan de WebControl donde agrega controles preexistentes al control dentro del método CreateChildControls . Esto proporciona una gran flexibilidad, pero la falta de soporte del diseñador sin codificación adicional. Sin embargo, son muy portátiles, ya que se pueden compilar en una DLL.
- Controles personalizados : similares a los controles compuestos personalizados, estos se agregan a un proyecto de biblioteca de control web. La representación del control está completamente controlada por el programador anulando el método Render .
Mis pensamientos..
OK, así que mientras jugaba con materiales compuestos personalizados, encontré lo siguiente:
- Tiene poco o ningún control sobre la salida de HTML por lo que es difícil "depurar".
- CreateChildControls (y los métodos subsiguientes) pueden ocuparse realmente con Controls.Add (myControl) en todas partes.
- Encontré que las tablas de renderizado (ya sea para el diseño o el contenido) son considerablemente incómodas.
Las preguntas)..
Entonces, lo admito, soy nuevo en esto, así que podría estar muy fuera de lugar con algunos de los puntos mencionados anteriormente.
- ¿Usas Composites?
- ¿Tiene algún truco para controlar el resultado HTML?
- ¿Simplemente dices "al diablo con eso" y sigues adelante y creas un control renderizado personalizado?
Es algo que estoy ansioso por tener realmente firme en mi mente, ya que sé cuánto buen control de desarrollo puede reducir el tiempo de desarrollo general.
Espero sus respuestas ^ _ ^
A menudo uso controles compuestos. En lugar de anular Render o RenderContents, simplemente asigne cada Control a 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 una representación rápida y sucia, 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;
};
Digo adelante con el control personalizado. Encuentro que en la mayoría de los casos el compuesto puede ser más fácil de hacer y usar en un UserControl, pero cualquier cosa más allá de eso y necesitaría tener un grado de control más fino (juego de palabras no intencionado) para merecer su propia estrategia de renderizado.
Tal vez haya controles que sean lo suficientemente simples como para merecer un compuesto (por ejemplo, un cuadro de texto combinado con un datepicker basado en javascript / dhtml, por ejemplo), pero más allá de ese ejemplo, parece que los controles personalizados son el camino a seguir.
El uso de controles compuestos personalizados tiene un punto en una situación en la que tiene una aplicación web grande y desea reutilizar grandes porciones en muchos lugares. Luego, solo agregaría controles secundarios de los que está desarrollando en lugar de repetirlos. En un proyecto grande que he trabajado recientemente, lo que hicimos es lo siguiente:
- Cada control compuesto tiene un contenedor. Usado como un envoltorio para todo dentro del control.
- Cada control compuesto tiene una plantilla. Un archivo ascx (sin la directiva <% Control%>) que solo contiene el marcado para la plantilla.
- El contenedor (que es un control en sí mismo) se inicializa a partir de la plantilla.
- El contenedor expone propiedades para todos los otros controles en la plantilla.
- Solo usa esto .Controles.Agregar ([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 arrojar excepciones cuando no se encuentre un control en la plantilla. Por supuesto, es probable que sea una exageración en una aplicación pequeña. Si no tiene código reutilizado y marcado y solo desea escribir controles simples, es mejor que use los controles de usuario.
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 sistema ascx usted y un diseñador pueden trabajar por separado. Si no planifica cambios reales de CSS / marcado / diseño en los propios controles más adelante, puede ir con un control renderizado personalizado. Como dije, mi enfoque solo es relevante para escenarios más complicados (y es probable que necesiten un diseñador :))
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, usted 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 asocia al árbol de control. Entonces su control compuesto realmente funcionaría como más de un controlador, y el archivo .ascx sería como una vista.
¡Esto le ahorrará la molestia de tener que crear una instancia de todo el árbol de control y darle un estilo al control en C #!
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);
}