Sto cercando di personalizzare la generazione del codice di Windows Forms Designer per InitializeComponent
. L'articolo MSDN "Customizing Code Generation in the .NET Framework Visual Designers" contiene una sezione "Controlling Code Generation" che spiega le basi di come ciò può essere fatto.Come posso personalizzare la generazione del codice di InitializeComponent? Più specificamente, come posso post-elaborare tutto il codice generato?
ho seguito da vicino un esempio nell'articolo di cui sopra:
//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;
}
}
Ora collego questo fino alla mia forma SomeForm
:
[DesignerSerializer(typeof(SomeFormSerializer), typeof(CodeDomSerializer))]
class SomeForm : Form { … }
La Progettazione form potrebbe quindi generare il codice seguente 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`) */
}
Si noti che il comme nt // CODEDOM WAS HERE
non è stato aggiunto come prima riga in InitializeComponent
, ma solo come prima riga del blocco di codice che gestisce le proprietà dell'oggetto modulo stesso.
Cosa dovrei fare se volessi essere in grado di modificare il CodeDOM generato dell'intero metodo, e non solo della parte che riguarda un oggetto specifico?
Contesto: Perché voglio farlo? In Windows Form, se si desidera la conversione del valore flessibile durante l'associazione dei dati, in genere si deve ricorrere agli abbonamenti agli eventi
Format
eParse
di un particolare oggettoBinding
. Quindi sto creando una sottoclasse specializzataBinding
(chiamiamolaConvertingBinding
) che semplifica questo processo un po '.Ora, il problema è che quando i collegamenti dati sono impostati in Progettazione Windows Form, il codice generato crea istanze di
Binding
; tuttavia, vorrei che il progettista istanziasse invece la mia sottoclasse specializzata. Il mio attuale approccio è quello di consentire al progettista di creare prima un albero CodeDOM, quindi di camminare su quell'albero e sostituire tutte le istanze diBinding
con le istanze diConvertingBinding
.
Questo è quasi quello che voglio. Questo sembra sufficiente per sostituire le istanze di 'Binding'; ma non riesco ancora ad accedere all'intero metodo, ad esempio le prime poche righe e le ultime poche righe in "InitializeComponent". – stakx
@stakx: le prime righe di 'InitializeComponent' sono sempre costituite da oggetti' CodeVariableDeclarationStatement'. Se apporti modifiche a uno di questi oggetti in 'CodeStatementCollection' o aggiungi un nuovo' CodeVariableDeclarationStatement' alla raccolta, tutte queste modifiche appariranno nelle prime righe. Qualsiasi altra riga 'CodeStatement' apparirà dopo tutte le righe' CodeVariableDeclarationStatement'. – nempoBu4