Estoy tratando de personalizar la generación de código del Diseñador de Windows Forms para InitializeComponent
. El artículo "Customizing Code Generation in the .NET Framework Visual Designers" de MSDN contiene una sección "Controlling Code Generation" que explica los conceptos básicos de cómo se puede hacer esto.¿Cómo puedo personalizar la generación de código de InitializeComponent? Más específicamente, ¿cómo puedo postprocesar todo el código generado?
He seguido de cerca un ejemplo en el artículo anterior:
//using System.ComponentModel.Design.Serialization;
class SomeFormSerializer : CodeDomSerializer
{
public override object Serialize(IDesignerSerializationManager manager,
object value)
{
// first, let the default serializer do its work:
var baseSerializer = (CodeDomSerializer)manager.GetSerializer(
typeof(Form).BaseType, typeof(CodeDomSerializer));
object codeObject = baseSerializer.Serialize(manager, value);
// then, modify the generated CodeDOM -- add a comment as the 1st line:
if (codeObject is CodeStatementCollection)
{
var statements = (CodeStatementCollection)codeObject;
statements.Insert(0, new CodeCommentStatement("CODEDOM WAS HERE"));
}
// finally, return the modified CodeDOM:
return codeObject;
}
}
Ahora conectar esto a mi forma SomeForm
:
[DesignerSerializer(typeof(SomeFormSerializer), typeof(CodeDomSerializer))]
class SomeForm : Form { … }
El Diseñador de formularios podría entonces generar el siguiente código InitializeComponent
:
private void InitializeComponent()
{
… /* (general setup code, such as a call to `this.SuspendLayout`) */
//
// someButton
//
… /* (someButton's properties are set) */
// CODEDOM WAS HERE!
//
// SomeForm
//
… /* (form's properties are set) */
… /* (general setup code, such as a call to `this.ResumeLayout`) */
}
Tenga en cuenta que el comme nt // CODEDOM WAS HERE
no se agregó como la primera línea en InitializeComponent
, pero solo como la primera línea del bloque de código que trata con las propiedades del objeto de formulario en sí.
¿Qué tendría que hacer si quisiera poder modificar el CodeDOM generado de todo el método, y no solo de la parte que trata con un objeto específico?
Antecedentes: ¿Por qué quiero hacer esto? En Windows Forms, si se quiere una conversión de valor flexible durante el enlace de datos, generalmente se debe recurrir a la suscripción a los eventos
Format
yParse
de algún objeto particularBinding
. Así que estoy creando una subclase especializadaBinding
(llamémoslaConvertingBinding
) que simplifica un poco este proceso.Ahora, el problema es que cuando los enlaces de datos se configuran en el Diseñador de Windows Forms, el código generado crea instancias de
Binding
; sin embargo, me gustaría que el diseñador instanciara mi subclase especializada en su lugar. Mi enfoque actual es permitir que el diseñador cree primero un árbol CodeDOM, luego recorra ese árbol y reemplace todas las instancias deBinding
por instanciaciones deConvertingBinding
.
Esto es casi lo que quiero. Esto parece suficiente para reemplazar las instancias 'Binding'; pero todavía no puedo acceder a todo el método, es decir, las primeras líneas y las últimas líneas en 'InitializeComponent'. – stakx
@stakx: las primeras líneas en 'InitializeComponent' siempre están compuestas de objetos' CodeVariableDeclarationStatement'. Si realiza cambios en cualquiera de estos objetos en 'CodeStatementCollection' o agrega un nuevo' CodeVariableDeclarationStatement' a la colección, todos estos cambios aparecerán en las primeras líneas. Cualquier otra línea 'CodeStatement' aparecerá después de todas las líneas' CodeVariableDeclarationStatement'. – nempoBu4