2010-08-11 11 views
5

Non sono sicuro quale sia il modo migliore per formularlo, ma mi chiedo se un accesso al nome variabile dinamico può essere fatto in C# (3.5).Nome variabile dinamico utilizzato in C# per WinForms

Ecco il codice che attualmente sto cercando di "rendere più smart" o rendere più elegante con un ciclo.

private void frmFilter_Load(object sender, EventArgs e) 
    { 
     chkCategory1.Text = categories[0]; 
     chkCategory2.Text = categories[1]; 
     chkCategory3.Text = categories[2]; 
     chkCategory4.Text = categories[3]; 
     chkCategory5.Text = categories[4]; 
     chkCategory6.Text = categories[5]; 
     chkCategory7.Text = categories[6]; 
     chkCategory8.Text = categories[7]; 
     chkCategory9.Text = categories[8]; 
     chkCategory10.Text = categories[9]; 
     chkCategory11.Text = categories[10]; 
     chkCategory12.Text = categories[11]; 


    } 

C'è un modo per fare qualcosa di simile ("chkCategory" + i.ToString()). Testo?

+0

Posso mostrare completamente la mia ignoranza sulla parte dinamica delle nuove funzionalità di C#, ma ho pensato che C# fosse un linguaggio compilato. Pertanto, per ottenere ciò, è necessario creare un'istanza del compilatore, generare il codice e quindi eseguire il codice all'interno del contesto del thread proprietario dei controlli. Non è pratico. –

+0

Domanda generale in risposta alle risposte: Quando si utilizza il progettista WinForms, qual è il metodo migliore per gestire l'array di checkbox? – Awaken

+0

Che tipo di riflessione è stata inventata per (Nel tuo caso speciale puoi anche accedere al controllo con il loro nome). – codymanix

risposta

5
for(...) 
{ 
    CheckBox c = this.Controls["chkCategory" + i.ToString()] as CheckBox ; 

    c.Text = categories[i]; 
} 
+0

Perfetto. Ha funzionato come un fascino. – Awaken

0

Non è necessario dinamico per quello. Metti chkCategory1 - 12 in un array, e ciclicamente attraverso un ciclo for. Ti suggerisco di tenerlo in un campo e inizializzarlo in fase di costruzione del modulo, perché chkCategory sembra essere correlato. Ma se volete un semplice esempio di come farlo in quel metodo semplice, allora sarebbe qualcosa di simile:

private void frmFilter_Load(object sender, EventArgs e) 
{ 
    var chkCategories = new [] { chkCategory1, chkCategory2, chkCategory3, .......... }; 
    for(int i = 0 ; i < chkCategories.Length ; i++) 
     chkCategoies[i].Text = categories[i]; 
} 

si sa di più circa l'applicazione, in modo da potrebbe forse evitare di scrivere tutti i nomi di controllo - per esempio, se sono posti su un controllo genitore comune, li puoi trovare passando attraverso i suoi figli.

+0

Non penso che l'OP significhi dynamic 'dynamic'. –

+0

Come funziona con il designer WinForms? Dovrei definire manualmente tutti i posizionamenti e le proprietà nel codice? – Awaken

0

No, ma si potrebbe fare qualcosa di simile (non testata, fate attenzione di errori di sintassi):

private readonly CheckBox[] allMyCheckboxes = new CheckBox[] { chkCategory1, chkCategory2, ... } 

Poi basta fare

for (i = 0; i < 12; i++) allMyCheckboxes[i].Text = categories[i]; 
6

Sì, è possibile utilizzare

Control c = this.Controls.Find("chkCategory" + i.ToString(), true).Single(); 
    (c as textBox).Text = ...; 

Aggiungere un controllo degli errori e avvolgerlo in un metodo piacevole (estensione).


Edit: Restituisce Control[] quindi o un [0] o un .Single() sono necessari alla fine. Aggiunto.

+0

Bello! Sono corretto dal mio commento lasciato sulla domanda. –

+0

@faux trot, questa è una funzione di libreria, non una lingua. Non è proprio l'identificatore su cui stiamo cercando, ma la proprietà Name. I 2 sono comunque sincronizzati. –

+0

Grazie. Questa è una tecnica che non conoscevo, ma ho un paio di situazioni in cui sarà bello. – Awaken

2

È possibile farlo con la riflessione. Ma non farlo.

È più appropriato creare un'istanza di controlli, aggiungerli a livello di codice al modulo e indicizzarlo.

1

A volte può aiutare a mettere i controlli in un array o la raccolta in quanto tale:

Checkbox[] chkCataegories = new Checkbox[] { chkCategory1, chkCategory2 ... }; 
for(int i = 0; i < chkCategories.Length; i++) 
    chkCategories[i].Text = categories[i]; 

Come un altro approccio, è possibile creare dinamicamente le caselle di controllo in fase di esecuzione, invece di tempi di progettazione:

for(int i = 0; i < categories.Length; i++) 
{ 
    Checkbox chkCategory = new chkCategory { Text = categories[i] }; 
    someContainer.Controls.Add(chkCategory); 
} 

Almeno con i controlli creati dinamicamente, non è necessario modificare la GUI o il codice del modulo ogni volta che si aggiungono nuove categorie.

+0

C'è un buon modo per farlo usando il designer WinForms in VS? O dovrei abbandonare il progettista e compilare il modulo con codice dinamicamente nel caricamento? – Awaken

0

"this.Controls [" chkCategory "+ i.ToString()]" e "this.Controls.Find (" chkCategory "+ i.ToString(), true)" entrambi non funzionano ... il in precedenza ti informa che i contenuti di [] non sono int e quest'ultimo che ControlCollection non contiene una definizione per Trova.

Utilizzare "Control myControl1 = FindControl (" TextBox2 ");" anziché.

Avevo bisogno di questo modulo mentre stavo collegando un altro array, estraendo valori e usandoli per compilare i campi modulo. Molto più semplice cercare label1, label2, label3, ecc.