PDA

View Full Version : [C#]popolamento controlli visuali


RaouL_BennetH
25-11-2008, 16:41
Ciao a tutti :)

Ho questo piccolo problema:

ho un oggetto combobox che ha un'origine dati.

Supposto di avere una tabella: table(id, descrizione)

non ho problemi a popolare il combo con tutti i valori contenuti nel campo
descrizione.

Quello che invece non riesco a capire è come popolare un altro elemento sulla base del valore contenuto nel combo;

per esempio, se volessi una casella di testo che mi contiene l'id relativo al valore 'descrizione', dovrei fare un'altra select e popolare poi la casella di testo.

Questo ragionamento ha però secondo me un difetto di base:

se ho due valori nel campo 'descrizione' uguali, non ha senso fare una select
perchè non sarei certo di aver scelto la 'descrizione' giusta.

Per essere più chiaro:


tabellaProva:

id - - descrizione
1 - - verde
2 - - rosso
3 - - verde



ora popolo la combobox ed avrò quindi:


verde
rosso
verde


come faccio a ricavare senza ambiguità il valore di 'id' da mettere in un altro controllo ?

Grazie mille :)

RaouL.

gugoXX
25-11-2008, 17:15
Vedi un po' se ti aiuta


namespace ComboStudy
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PopCombo();
}

public void PopCombo()
{
comboBox1.Items.Clear();
comboBox1.Items.Add(new BusinessObject(10, "Verde"));
comboBox1.Items.Add(new BusinessObject(20, "Rosso"));
comboBox1.Items.Add(new BusinessObject(30, "Verde"));
}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
BusinessObject bo = comboBox1.SelectedItem as BusinessObject;
if (bo != null)
{
string str=string.Format("Indice {0} - ID {1}, STR {2}",comboBox1.SelectedIndex,bo.ID,bo.str);
MessageBox.Show(str);
}
}
}

public class BusinessObject
{
public int ID;
public string str;

public BusinessObject(int p_id, string p_str)
{
ID = p_id;
str = p_str;
}

public override string ToString()
{
return str;
}
}
}

RaouL_BennetH
25-11-2008, 17:16
Ho fatto un piccolo passo avanti mediante l'uso di un dizionario e aggiungendo un altro combobox al posto della textbox:



//ottengo i dati dalla select, li carico nel dizionario e poi nel form:

foreach(KeyValuePair<int, string> k in classeProva.GetDizionario())
{
comboKey.Items.Add(k.Key);
comboColore.Items.Add(k.Value.ToString());
}




Benone, ora ho tutti i dati che mi servono ma....
devo capire ancora questo:

se scelgo un colore diverso in comboColore, mi deve variare anche il corrispondente in comboKey.

RaouL.

Piccolo Edit:

Non avevo visto ancora il tuo suggerimento :(

RaouL_BennetH
25-11-2008, 17:30
Ho risolto in modo credo non proprio brillante:

Mi sono detto, dato che quando popolo le combo con i valori del dizionario, gli index sono allineati, quindi, se cambio l'index sul primo combo, posso prenderne la posizione ed assegnare la stessa sul secondo combo.

Cioè:



private void comboColore_SelectedIndexChanged(object sender, EventArgs e)
{
comboKey.SelectedIndex = comboColore.SelectedIndex;
}



.... non picchiatemi ....

RaouL.

gugoXX
25-11-2008, 17:55
Allora non ho capito.
Comunque la soluzione e' (quasi) sempre popolare la combo direttamente con gli oggetti che si vogliono rappresentare, non con solo la loro rappresentazione (che appunto e' senza chiave)

RaouL_BennetH
25-11-2008, 18:15
Allora non ho capito.
Comunque la soluzione e' (quasi) sempre popolare la combo direttamente con gli oggetti che si vogliono rappresentare, non con solo la loro rappresentazione (che appunto e' senza chiave)



Scusami gugoXX, non credo di aver capito bene; in sostanza dici che non è molto corretto popolare solo con i "records" ottenuti dall'origine dati ?

Grazie mille :)

RaouL.

gugoXX
25-11-2008, 18:20
No, anzi, l'opposto.
E' opportuno popolare le combo (e altri controlli) proprio con i record ottenuti dal database, e non solo una descrizione.

Dove ciascun record avra' chiave, descrizione e tutto il resto.
In questo modo quando selezionerai l'elemento saprai tutto di esso, descrizione e chiave compresi.
Sulla base della chiave quindi potrai agire su altri elementi, lanciare altre query, etc.
Prima avevo postato un esempio, forse l'avevi perso.

RaouL_BennetH
25-11-2008, 18:26
No, anzi, l'opposto.
E' opportuno popolare le combo (e altri controlli) proprio con i record ottenuti dal database, e non solo una descrizione.

Dove ciascun record avra' chiave, descrizione e tutto il resto.
In questo modo quando selezionerai l'elemento saprai tutto di esso, descrizione e chiave compresi.
Sulla base della chiave quindi potrai agire su altri elementi, lanciare altre query, etc.
Prima avevo postato un esempio, forse l'avevi perso.

Ah ok :)

Eh si, ho messo un edit perchè l'ho notato solo dopo :(

Vincenzo1968
25-11-2008, 19:46
No, anzi, l'opposto.
E' opportuno popolare le combo (e altri controlli) proprio con i record ottenuti dal database, e non solo una descrizione.

Dove ciascun record avra' chiave, descrizione e tutto il resto.
In questo modo quando selezionerai l'elemento saprai tutto di esso, descrizione e chiave compresi.
Sulla base della chiave quindi potrai agire su altri elementi, lanciare altre query, etc.
Prima avevo postato un esempio, forse l'avevi perso.

Ohé Gugo,

una domanda:

con la API è possibile associare un puntatore a ogni voce di una listbox(o combobox) tramite le funzioni GetItemDataPtr/SetItemDataPtr.
Il puntatore può puntare a dati semplici, come int, o a dati più complessi, come una struct.
Non esiste, in C#, qualcosa di simile?

:bimbo:

gugoXX
25-11-2008, 19:56
Certo.
Se vedi nel mio esempio, la combobox ha una proprieta'
Items
che sono gli oggetti contenuti nella combobox.
La combobox mostrera' il risultato della ToString() di ciascuno di questi elementi.
Ma ogni elemento puo' essere del tipo che si vuole.
Tutti gli oggetti hanno un-implementazione di base della ToString(), anche se e' bene effettuarne l'override, proprio per permettere il popolamento con una stringa custom.

Items implementa l'interfaccia IEnumerable, e come tale la si puo' trattare, con Add, Remove, foreach, Clear, etc.

Quindi, quando si aggiunge un'istanza di una classe (che e' per riferimento in C), di fatto si aggiunge solo il puntatore ad Items.
Quandi si aggiunge invece una struttura o un tipo Value base, di fatto si aggiunge una nuova copia ad Items. Sotto la coperta viene creato al volo un oggetto il cui puntatore viene aggiunto ad Items. (A differenza del C++ pero' la distruzione di quest'oggetto creato al volo verra' demandata al Garbage Collecor, una volta che l'oggetto verra' scodato da Items)

Vincenzo1968
25-11-2008, 20:11
Grazie mille ;)

Approfitto per precisare che ricordavo male. La funzioni di cui parlavo sono implementate su MFC. Per la API bisogna utilizzare i messaggi CB_GETITEMDATA/CB_SETITEMDATA o le macro ComboBox_GetItemData/ComboBox_SetItemData.

:bimbo: