Gambas-it

Archivi (sola lettura) => Programmazione (Gambas 2) => Topic aperto da: teox99 - 08 Gennaio 2009, 15:28:44

Titolo: Combobox
Inserito da: teox99 - 08 Gennaio 2009, 15:28:44
volevo sapere se è possibile dare un valore agli item nella combobox
(tipo la select in html)

ComboBox1.Add([Item AS String], [Index AS Integer])

per capirci Index come String invece di un Index come Integer!
Titolo: Re: Combobox
Inserito da: Fabrizio - 08 Gennaio 2009, 19:17:53
la mia non è una risposta anzi....
Io ho provato a fare questo:

combobox.add("pippo",4)
combobox.add("pluto",6)

ma quando si va a leggere l'indice questo è
0 per pippo
1 per pluto
quindi direi che non solo non si può assegnare l'indice come stringa, ma neanche lo si può fare come integer visto che si prende i valori di default.

Aspetto conferma per questo.

e poi, la lettura dell'indice su selezione, a quale evento corrisponde? io ho provato ma riesco a farlo solo su evento click, che per altro viene attivato durante .add

Nel lavoro che sto facendo io le combo le faccio mettendo:
la TextBox, a fianco un pulsante con la freccia, sotto una ColumnView all'interno di un Hbox.
Normalmente 'Hbox è invisibile, viene reso visibile dalla pressione del pulsante e torna invisibile quando il mouse esce dal hbox.

Tutto in quanto usando la columnview posso gestire meglio i dati come voglio.

bye
Titolo: Re: Combobox
Inserito da: md9327 - 09 Gennaio 2009, 10:17:26
L'indice, nel caso delle combo e delle listbox, corrisponde alla posizione della stringa nell'array ".List" dell'oggetto; se tenti di inserire un valore in una posizione inesistente (vedi index=5), mentre l'array è vuoto, non è cosa gradita. Il metodo dell'oggetto non ritorna errore (e questo può essere buono), ma non ti avverte di questo problema (tocca stare attenti...).

Un esempio puoi farlo con un semplice array:

Codice: [Seleziona]

DIM arr AS NEW String[] 'creo un array vuoto (0 items)

arr[10] = "PIPPO" 'ERRORE!
arr.Add("PIPPO") 'inserisce l'elemento come primo item dell'array
PRINT arr[0]
>PIPPO
arr.Add("PIPPO",10) 'e gli altri 9 item prima? me li devo creare io Gambas?
                    'io lo inserisco in fondo all'elenco, così per non
                    'sbagliare, che in questo caso è la posizione 0 (zero)
PRINT arr[0]
>PIPPO


L'utilità dell'indice, è quando si ha necessità di inserire un elemento (o più) in un array già popolato ovvero, quando occorre che il nuovo elemento vada in elenco prima di altri, come ad esempio:

Codice: [Seleziona]

DIM arr AS NEW String[10] 'creo un array di 10 elementi

arr[5] = "PIPPO"
PRINT arr[5]

arr.add("PLUTO",5)
PRINT arr[5]
>PLUTO
PRINT arr[6]
>PIPPO


l'inserimento dell'item sposta in basso l'item 5 precedente, e il nuovo viene inserito nella posizione del precedente.

Spero di aver chiarito il giochetto.

Riguardo all'evento di selezione di un item della combo, hai tre modi per capire quale item è selezionato, e quale testo contiene:

.Text 'ritorna il testo selezionato

.Selection 'ritorna un oggetto con le informazioni necessarie (vedi doc)

.Index 'ritorna l'indice del testo selezionato, riferito all'array

Per capire quando cambia, puoi usare l'evento Change, che si attiva quando viene modificato il testo visualizzato dalla combo (o quando viene sostituito da un'altro della lista); questo sia se la combo è ReadOnly (non editabile) o meno.

Riguardo all'ultima serie di controlli, con cui hai creato una sorta di oggetto, non capisco se il motivo è la sostituzione della combobox o altro.
Titolo: Re: Combobox
Inserito da: Fabrizio - 09 Gennaio 2009, 12:14:33
Il fatto è che come indice a me serve l'id che nel database fa da chiave primaria e come text la descrizione del record. (La columnview viene popolata da una query)

es:
tabella clienti
id----nome
4-----pippo
27----pluto

con la combobox da me creata scelgo pippo o pluto e da li ad esempio apro una finestra per l'edit di tutti i campi relativi a quello selezionato tramite la combo.
spero di essermi spiegato.

Naturalmente aspetto consigli per fare la stessa cosa in modo più semplice !

(Se esistesse l'ufficio per la complicazione degli affari semplici mi assumerebbero subito)
Titolo: Re: Combobox
Inserito da: md9327 - 09 Gennaio 2009, 20:05:21
In effetti, a te servirebbe un tag, corrispondente ad ogni elemento della lista, contenente l'id del record, ma in Gambas non c'è modo.

Ad ogni modo credo puoi fare così, sempre che non ti serva un ordine degli elementi (è ovvio che è un esempio, ed un'idea venuta al volo...):

1) crei un array di stringhe

2) fai un bel loop in cui aggiungi elementi in questo array

3) ogni stringa è composta in questo modo:

   array.Add(Str(id) & "|" & valore)

4) popoli contemporaneamente anche la combo:

   combo.Add(valore)

In questo modo hai un'array di base, che corrisponde, a livello di indice elemento, con l'elenco della combo; una volta determinato quale item ha selezionato l'utente, vai nell'array e ti tiri fuori l'id, estraendolo dalla stringa:

   nIndex = combo.Index
   nID = Int(Split(array[nIndex][0])
   sValue = Split(array[nIndex][1] 'oppure prendi il testo dalla combo
Titolo: Re: Combobox
Inserito da: Fabrizio - 09 Gennaio 2009, 20:18:39
può essere un'idea, comunque ora che Leo mia ha svelato a fondo come utilizzare la columnview non la mollo più, la userò pure per farmi il caffè al mattino! :-)

tks
Titolo: Re: Combobox
Inserito da: md9327 - 10 Gennaio 2009, 15:12:53
Se riesci a farti fare il caffè, avvertimi!!! :-)
Titolo: Re: Combobox
Inserito da: tornu - 15 Gennaio 2009, 21:53:50
Buona sera a tutti,

mi introduco in questa discussione per non aprirne una nuova, visto che il mio problema è inerente la funzionalità di una ComboBox è ha a che fare comunque con quanto discusso, ho questo codice:

Codice: [Seleziona]

PRIVATE cboItems AS NEW Object[]
PUBLIC SUB Button1_Click()
Result = conn.db.Exec("SELECT campo1, campo2 FROM tabella")  
END  

PUBLIC SUB ComboBox1_Click()  
FOR EACH Result
ComboBox1.Add(Result!campo2)
cboItems.Add([Result!campo1, Result!campo2])
NEXT  
Label1.Text = cboItems[ComboBox1.Index][0]  
END


ho la necessità che il primo item (index 0) della ComboBox sia vuoto e il Result sia accodato a partire dall'index 1.

......il caffè lo prendo al bar.... :-)
Titolo: Re: Combobox
Inserito da: fsurfing - 15 Gennaio 2009, 23:14:40
potresti dare un

ComboBox1.Add("")  


prima di

ComboBox1.Add(Result!campo2)
cboItems.Add([Result!campo1, Result!campo2])
NEXT  
Label1.Text = cboItems[ComboBox1.Index][0]  
END



ma forse non ho capito bene il problema...
Titolo: Re: Combobox
Inserito da: tornu - 16 Gennaio 2009, 00:27:06
Soluzione già provata ma non funziona perchè quando clicco sulla combo inserisce tra un dato e l'altro della lista un item vuoto e a me serve solo all'inizio della lista (come primo dato) e quando seleziono l'ultimo dato mi dà il seguente errore:

Out of bounds
Titolo: Re: Combobox
Inserito da: md9327 - 16 Gennaio 2009, 14:34:48
L'item vuoto deve essere inserito prima del ciclo FOR...NEXT, e non all'interno.
A volte, però, è necessario inserire una stringa composta da uno spazio, altrimenti si corre il rischio che la combo la rigetti.
Per far comparire questo campo vuoto all'inizio della lista, è necessario disattivare la proprietà Sort della combo, altrimenti potrebbe spostarti gli elementi secondo logica di ordinamento (anche se lo spazio è il prio carattere stampabile...).
Titolo: Re: Combobox
Inserito da: tornu - 16 Gennaio 2009, 20:48:17
Esatto!
Inserendo l'item vuoto prima del ciclo FOR...NEXT lo mette come primo elemento della lista, però rimane il problema che cliccando sull'ultimo dato della lista va fuori dai limiti generando l'errore: Out of bounds

come posso risolvere questo problema?
Titolo: Re: Combobox
Inserito da: leo72 - 17 Gennaio 2009, 00:32:51
Scusa, come può essere che cliccando semplicemente su un elemento di un ComboBox creato con il metodo Add() ti vada fuori indice?
Non è che nel codice di controllo del click hai una variabile o una matrice che non tiene conto dell'aumento di numero degli elementi? Potresti postare il codice dell'evento ComboBox_Click() per verificare?
Titolo: Re: Combobox
Inserito da: tornu - 17 Gennaio 2009, 01:14:11
Codice: [Seleziona]

PRIVATE cboItems AS NEW Object[]
PUBLIC SUB Button1_Click()
Result = conn.db.Exec("SELECT campo1, campo2 FROM tabella")
ComboBox1.Add(" ")  
FOR EACH Result  
ComboBox1.Add(Result!campo2)  
cboItems.Add([Result!campo1, Result!campo2])
NEXT  
END
   
PUBLIC SUB ComboBox1_Click()  
Label1.Text = cboItems[ComboBox1.Index][0]  
END


Ho ripostato il codice essendo errato quello postato precedentemente, ma la sostanza non cambia va sempre fuori indice quando clicco sull'ultimo dato della lista.
Titolo: Re: Combobox
Inserito da: leo72 - 17 Gennaio 2009, 10:12:22
E' come ti avevo detto. Non tieni conto del fatto che la numerazione negli oggetti e nei vettori in Gambas inizia dall'indice 0 e che hai aggiunto un elemento in più a ComboBox1 rispetto a cboItems.

Quando chiedi l'oggetto ComboBox1.Index a cboItems, avendo aggiunto un elemento con spazio vuoto al primo ma non al secondo, non tieni conto della differenza negli indici (cboItems è lungo un elemento in meno rispetto a ComboBox1). Per cui chiedi ad esempio l'elemento 4 quando cboItems ne contiene 3.

Quindi, o chiami l'elemento (ComboBox1.Index - 1)
Codice: [Seleziona]

PRIVATE cboItems AS NEW Object[]
PUBLIC SUB Button1_Click()
  Result = conn.db.Exec("SELECT campo1, campo2 FROM tabella")
  ComboBox1.Add(" ")  
  FOR EACH Result  
    ComboBox1.Add(Result!campo2)  
    cboItems.Add([Result!campo1, Result!campo2])
  NEXT  
END
   
PUBLIC SUB ComboBox1_Click()  
Label1.Text = cboItems[ComboBox1.Index - 1][0]  
END


oppure aggiungi anche a cboItems un elemento spaziatore:

Codice: [Seleziona]

PRIVATE cboItems AS NEW Object[]
PUBLIC SUB Button1_Click()
  Result = conn.db.Exec("SELECT campo1, campo2 FROM tabella")
  ComboBox1.Add(" ")  
  cboItems.Add(" ", " ")
  FOR EACH Result  
    ComboBox1.Add(Result!campo2)  
    cboItems.Add([Result!campo1, Result!campo2])
  NEXT  
END
   
PUBLIC SUB ComboBox1_Click()  
Label1.Text = cboItems[ComboBox1.Index][0]  
END


P.S.:
indenta il tuo codice, ne guadagnerai in leggibilità quando userai molti cicli annidati (es. IF/THEN dentro a FOR/NEXT dentro a....).
Titolo: Re: Combobox
Inserito da: tornu - 17 Gennaio 2009, 14:59:09
Grazie leo per le delucidazioni e la soluzione che mi hai postato.

Solo due piccole osservazioni (se mi posso permettere):
sicuramente un errore di digitazione da parte tua, questo pezzo di codice va scritto con le parentesi quadre
Codice: [Seleziona]
cboItems.Add([" ", " "]) 


Nel primo esempio che mi hai fatto se clicco sull'item vuoto va in errore 'Out of bounds' selezionando qualsiasi altro dato della lista, ok. Sicuramente ti sei scordato qualcosa.

Un ultima cortesia (abbi pazienza, ma mi piace capire), mi spieghi meglio questo consiglio:
Citazione
P.S.: indenta il tuo codice, ne guadagnerai in leggibilità quando userai molti cicli annidati (es. IF/THEN dentro a FOR/NEXT dentro a....).


Grazie.
Titolo: Re: Combobox
Inserito da: leo72 - 17 Gennaio 2009, 15:16:15
1)
Sì, è con le [].

2)
Perché alla fine mi sono confuso anch'io. Non tengo conto del fatto che cliccando sull'item n°0 in ComboBox chiedi di caricare l'indice -1 in cboItems. Usa il 2° esempio, è più semplice e più corretto.

3)
Indentare significa allineare il codice spostando i cicli annidati tipo appunto i FOR, gli IF, ecc... più a destra del restante. In questa maniera la lettura del codice è semplificata e si capisce subito a cosa si riferisce un ENDIF o un NEXT se ne hai più di uno annidati. E' un'abitudine che imparai col Pascal e che, poi, mi sono portato dietro anche nel VB prima ed in Gambas poi Adesso, che studio il Python, è un "obbligo", non una scelta, però poi a distanza di mesi ti rendi conto di quanto è stato comodo fare così quando devi rileggere del codice.
Per capirsi, guarda questa porzione di codice:
Codice: [Seleziona]

IF A=1 THEN
IF B=1 THEN
FOR L=1 TO N
C=C+1
FOR M=C TO X
V=V+1
IF G=1 THEN
F=F+1
ENDIF
NEXT
NEXT
ENDIF
ENDIF

e dimmi se ci hai capito qualcosa!

Adesso guarda la stessa porzione con l'indentazione:
Codice: [Seleziona]

IF A=1 THEN
  IF B=1 THEN
    FOR L=1 TO N
      C=C+1
      FOR M=C TO X
        V=V+1
        IF G=1 THEN
          F=F+1
        ENDIF
      NEXT
    NEXT
  ENDIF
ENDIF

capisci subito ad occhio a quale ciclo IF si riferisce ogni ENDIF, così come a quale FOR si riferisce ogni NEXT.
Non è più chiaro?
Titolo: Re: Combobox
Inserito da: tornu - 17 Gennaio 2009, 22:16:55
Grazie del consiglio che applicherò da adesso in poi e delle spiegazioni in merito all'indentazione. :ciao:
Titolo: Re: Combobox
Inserito da: madnessmike - 10 Aprile 2009, 14:10:36
Come faccio ad aggiungere in una combobox la lista dei file di una cartella remota ftp, ovviamente un file per riga?
Titolo: Re: Combobox
Inserito da: Ceskho - 10 Aprile 2009, 14:22:11
Dovresti inserire il comando

Codice: [Seleziona]
variabile_stringa = stringa_indirizzo_ftp
ComboBox.add(variabile_stringa, n)


in un cliclo for che esegue il comando "n" volte...dove "n" è il numero delle righe contenute nella cartella ftp...
Titolo: Re: Combobox
Inserito da: fsurfing - 10 Aprile 2009, 14:40:01
nel caso avessi una variabile array come contenitore dei file remoti puoi usare:


Codice: [Seleziona]

dim linee as string[]

combobox1.list=linee


Titolo: Re: Combobox
Inserito da: madnessmike - 11 Aprile 2009, 10:20:51
Bello quel codice, fsurfing, non lo sapevo, forse mi semplificherà il lavoro! :-P
Titolo: Re: Combobox
Inserito da: fsurfing - 11 Aprile 2009, 11:46:41
e lo so ...sono un grande!!!!!!!! :-P  :-P  :-P  :-P