ComboBox Readonly

Talvolta sarebbe utile rendere ReadOnly un ComboBox in modo che visualizzi solo il suo contenuto senza permettere modifiche.

Nativamente questo è possibile impostando la proprietà ReadOnly, ma in questo modo la leggibilità non è il massimo:

image image

Quello che servirebbe avere la possibilità di poter impostare il ComboBox in modalità ReadOnly come avviene per il TextBox, purtroppo questa modalità non è prevista in modo nativo mentre pare che in VB6 esistesse una proprietà Locked che non più stata implementata. Il suggerimento che viene dato su MSDN per implementare la funzionalità di Locked del VB6 è quello di impostare la proprietà DropDownStyle al valore DropDownList e impedire la selezione nell’evento MouseDown (a riguardo si veda Controllo ComboBox per gli utenti di Visual Basic 6.0).

Io invece ho preferito un altro approccio e cioè quello di creare un’estensione per il controllo ComboBox con un metodo SetReadOnly che va a creare a runtime un controllo TextBox impostato a ReadOnly e lo sovrappone al ComboBox.

image

Di seguito il codice per implementare tale funzionalità che potrà essere semplicemente utilizzata invocando il metodo SetReadOnly: cmbPorto.SetReadOnly(True)

Public Module ComboBoxExtensions

Private Const ReadOnlyTextBoxName As String = “txtReadOnly”

<System.Runtime.CompilerServices.Extension()> _
Public Sub SetReadOnly(ByVal combobox As System.Windows.Forms.ComboBox, _
ByVal value As Boolean)
Dim readOnlyTextBox As TextBox = GetReadOnlyTextBox(combobox)

If value AndAlso readOnlyTextBox Is Nothing Then
‘Creazione ReadOnly TextBox
readOnlyTextBox = New TextBox()
readOnlyTextBox.Name = ReadOnlyTextBoxName
readOnlyTextBox.ReadOnly = True
readOnlyTextBox.Multiline = True
readOnlyTextBox.Width = combobox.Width
readOnlyTextBox.Height = combobox.Height
readOnlyTextBox.Text = combobox.Text
readOnlyTextBox.Font = combobox.Font
combobox.Controls.Add(readOnlyTextBox)
AddHandler combobox.TextChanged, AddressOf ComboBox_TextChanged
ElseIf Not value AndAlso readOnlyTextBox IsNot Nothing Then
‘Rimozione ReadOnly TextBox
RemoveHandler readOnlyTextBox.TextChanged, AddressOf ComboBox_TextChanged
combobox.Controls.Remove(readOnlyTextBox)
readOnlyTextBox.Dispose()
readOnlyTextBox = Nothing
End If
End Sub

<System.Runtime.CompilerServices.Extension()> _
Public Function GetReadOnly(ByVal combobox As System.Windows.Forms.ComboBox) As Boolean
Return GetReadOnlyTextBox(combobox) IsNot Nothing
End Function

Private Function GetReadOnlyTextBox(ByVal comboBox As ComboBox) As TextBox
GetReadOnlyTextBox = Nothing

‘Ricerca ReaOnlyTextBox
For Each c As Control In comboBox.Controls
If TypeOf c Is TextBox AndAlso c.Name = ReadOnlyTextBoxName Then
GetReadOnlyTextBox = DirectCast(c, TextBox)
Exit For
End If
Next
End Function

Private Sub ComboBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim readOnlyTextBox = GetReadOnlyTextBox(DirectCast(sender, ComboBox))

If readOnlyTextBox IsNot Nothing Then
readOnlyTextBox.Text = DirectCast(sender, ComboBox).Text
End If
End Sub

End Module