Ridimensionare la larghezza della finestra a cascata di un ComboBox in base alla lunghezza testuale di un elemento della lista

Da Gambas-it.org - Wikipedia.

L'intenzione di questa pagina è mostrare come ridimensionare la larghezza della finestra a cascata di un ComboBox in base alla lunghezza testuale di un elemento (Item ), nel momento in cui si preme il tasto del mouse (Evento "_MouseDown") sulla parte a destra del ComboBox, definita dal simbolo della "vergatura", e che rappresenta il tastino di attivazione del ComboBox.

Purtroppo il suddetto specifico Evento non funziona, cliccando su quel settore destro del ComboBox, bensì solo cliccando sulla parte degli elementi testuali). Per risolvere il problema, bisogna tenere conto di come è formato attualmente il ComboBox.

Attualmente il ComboBox in Gambas è formato da almeno due Oggetti grafici, verificabili agevolmente invocando la sua Proprietà ".Children":

Public Sub Form_Open()

 Dim ob As Object
 
 For Each ob In ComboBox1.Children
   Print Object.Type(ob)
 Next

End

Si potrà notare, i due Oggetti - "Figli" del ComboBox - sono un Panel e TextBox. [Nota 1]

Coma sappiamo, per far apparire a cascata la finestra degli elementi testuali del ComboBox, è necessario cliccare sulla parte a destra dell'Oggetto definita dal sibolo della "vergatura".
Questa parte del ComboBox è formata dal suo primo Oggetto "Figlio", il Panel ; mentre la lista degli elementi testuali è contenuta nel secondo oggetto "Figlio": il TextBox.

Ebbene, per ottenere l'Evento "_MouseDown", quando si preme il tasto del mouse sulla parte destra del ComboBox (il suo tastino di attivazione), si deve agire sul primo "Figlio", ossia sull'Oggetto Panel.
Ovviamente si dovrà assegnare detto Panel ad un Guppo di Eventi, affinché tale Oggetto grafico possa scatenare l'Evento da noi desiderato.
A tale proposito va rilevato che non potremo utilizzare il Metodo "Object.Attach()", poiché in tal caso sarebbero compromessi, e pertanto non più attivabili, gli Eventi nativi e la stessa completa funzionalità del ComboBox.
Si dovrà, quindi, utilizzare la Classe "Observer", che consentità la contemporanea e piena funzionalità delle risorse sia dell'Oggetto "Figlio" (il Panel ) sia del ComboBox.

Mostriamo un esempio pratico:

Private Const LUNGCB As Byte = 60


Public Sub Form_Open()

 Dim pn As Panel
 Dim obs As Observer

 ComboBox1.W = LUNGCB
 ComboBox1.List = ["àèéìòù", "1234567890", "bbGTfddr", "abcde"]

' Individua il primo Oggetto "Figlio" del "ComboBox" (il "Panel"):
 pn = ComboBox1.Children[0]

' Pone sotto osservazione il "Panel" per la gestione dei suoi Eventi tipici:
 obs = New Observer(pn) As "Panel1"

End

Public Sub Panel1_MouseDown()

 Dim c As Short

 c = Individua()
 
' Calcola la dimensione della finestra a cascata del "ComboBox" in base alla quantità maggiore di caratteri contenuti nella sua lista degli elementi:
 ComboBox1.W = ComboBox1.Font.TextWidth(ComboBox1.List[c]) + 
               (ComboBox1.Font.TextWidth(ComboBox1.List[c]) / ComboBox1.List[c].Len)
 
End

Private Function Individua() As Short
 
 Dim s As String
 Dim cc As New Short[]
 Dim c As Short

 For Each s In ComboBox1.List
' Assegna il valore di ciascuna quantità di caratteri:
   cc.Push(String.Len(s))
 Next
' Ordina in modo "discendente" i valori presenti nel vettore di tipo "Short":
 cc.Sort(gb.Descent)

 For c = 0 To cc.Max
' Individua l'indice dell'elemento contenente la quantità di caratteri maggiore:
   If cc[0] == String.Len(ComboBox1.List[c]) Then Break  
 Next
 
 Return c
 
End

Public Sub Panel1_MouseUp()
 
' Ripristina in chiusura della finestra del "ComboBox" la dimensione originaria di tale Oggetto grafico:
 ComboBox1.W = LUNGCB
 ComboBox1.Pos = 0
 
End

Public Sub ComboBox1_Click()  

 ComboBox1.W = LUNGCB
 ComboBox1.Pos = 0
 
End

Uso del ComboBox con la Prprietà ".ReadOnly" impostata a "True"

Se si intende usare il ComboBox con la Prprietà ".ReadOnly" impostata a "True", si dovrà avere cura di eliminare la riga di comando:

ComboBox1.Pos = 0

dalle routine sopra presenti.


Note

[1] Va precisato che l'Oggetto ComboBox possiede due "Figli" Oggetti grafici, se la sua Proprietà ".ReadOnly" è lasciata al suo valore predefinito ovvero impostata a "FALSE". Qualora tale Proprietà sia impostata a "True", allora il ComboBox è costituito da un solo "Figlio": il Panel.