MarcD wrote: Try changing the DropDownStyle property to DropDownList. This can either be done through the designer or via code.
I heard this before but, IMHO setting it to dropdownlist makes it not readonly
because you you stil can chance the value, the best alternative is to chance enabled to false
Exactly, the user still has a chance to change the values.
In my case, based on the user group, I would like to provide an option to change combo value. Though I set the combo to dropdownlist, I just leftout with an option to disable the control, which looks ugly in the form with no legibility to the content inside the combo.
Any other solution?
I solved this once by checking if the value typed in was in the collection of added items. If it was, I accepted the value and did further processing. If it wasn`t in the collection, I discarded the value and stopped further processing. Maybe this approach could help you.
here is one more solution i find out
ComboBox cb = new ComboBox();
Point p = new Point(100, 100);
cb.Location = p;
cb.DropDownStyle = ComboBoxStyle.DropDownList;
- Proposed as answer by mjanz Tuesday, December 28, 2010 8:28 PM
Next code will make comboBox readOnly. To be more exact it will make textBox of the comboBox readOnly.
private bool m_readOnly = false;
private const int EM_SETREADONLY = 0x00CF;
internal delegate bool EnumChildWindowsCallBack( IntPtr hwnd, IntPtr lParam );
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[ DllImport( "user32.dll" ) ]
internal static extern int EnumChildWindows( IntPtr hWndParent, EnumChildWindowsCallBack lpEnumFunc, IntPtr lParam );
private bool EnumChildWindowsCallBackFunction(IntPtr hWnd, IntPtr lparam)
if( hWnd != IntPtr.Zero )
IntPtr readonlyValue = ( m_readOnly ) ? new IntPtr( 1 ) : IntPtr.Zero;
SendMessage( hWnd, EM_SETREADONLY, readonlyValue, IntPtr.Zero );
private void MakeComboBoxReadOnly( bool readOnly )
m_readOnly = readOnly;
EnumChildWindowsCallBack callBack = new EnumChildWindowsCallBack( this.EnumChildWindowsCallBackFunction );
EnumChildWindows( comboBox1.Handle, callBack, IntPtr.Zero );
I found the best way is to create an ExtenderProvider for the combo box whereas inside you change the dropdownstyle to simple and trap all keystrokes. You'll need to rebuild the project after you add the ReadOnlyComboProvider class. Then simply drag one of these from the toolbox onto your form and set the properties via a property window or via code.
Here's the code for the extender Provider:
ProvideProperty("ReadOnly", GetType(Control)), _
ProvideProperty("OrigDropDownStyle", GetType(Control))> _
PublicClass ReadOnlyComboProvider Inherits System.ComponentModel.Component Implements IExtenderProvider 'This hash table stores all the controls extended by this extender provider Friend htProvidedProperties As New Hashtable
#Region "IExtenderProvider" ''' <summary> ''' The Property should be Extend / Not for the TextBox classes ''' </summary> ''' <param name="extendee"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function CanExtend(ByVal extendee As Object) As Boolean Implements System.ComponentModel.IExtenderProvider.CanExtend If TypeOf extendee Is ComboBox Then Return True Else Return False End If End Function
#Region "Extensible Properties" Private Class ComboBoxProperties Public IsReadOnly As Boolean = False Public OrigComboBoxStyle As ComboBoxStyle = ComboBoxStyle.DropDown End Class
<Category("Read Only Combobox Provider")> _ Sub SetReadOnly(ByVal ctrl As Control, ByVal value As Boolean) Dim cbo As ComboBox = CType(ctrl, ComboBox) If value = True Then
cbo.DropDownStyle = ComboBoxStyle.SimpleElse
cbo.DropDownStyle = GetControlFromHashtable(ctrl).OrigComboBoxStyleEnd If
GetControlFromHashtable(ctrl).IsReadOnly = valueEnd Sub
<Category("Read Only Combobox Provider")> _ Function GetReadOnly(ByVal ctrl As Control) As Boolean Return GetControlFromHashtable(ctrl).IsReadOnly End Function
<Category("Read Only Combobox Provider")> _ Sub SetOrigDropDownStyle(ByVal ctrl As Control, ByVal value As ComboBoxStyle)
GetControlFromHashtable(ctrl).OrigComboBoxStyle = valueEnd Sub
<Category("Read Only Combobox Provider")> _ Function GetOrigDropDownStyle(ByVal ctrl As Control) As ComboBoxStyle Return GetControlFromHashtable(ctrl).OrigComboBoxStyle End Function
#Region "Behavior" Private Function GetControlFromHashtable(ByVal ctrl As Control) As ComboBoxProperties If htProvidedProperties.Contains(ctrl) Then Return DirectCast(htProvidedProperties(ctrl), ComboBoxProperties) Else Dim ProvidedProperties As New ComboBoxProperties 'Add A KeyPress Event Handler as the control is added to hash table AddHandler ctrl.KeyPress, AddressOf KeyPressHandler
htProvidedProperties.Add(ctrl, ProvidedProperties)Return ProvidedProperties End If End Function Private Sub KeyPressHandler(ByVal sender As Object, ByVal e As KeyPressEventArgs) Dim cboSender As ComboBox = CType(sender, ComboBox) If GetControlFromHashtable(cboSender).IsReadOnly = True Then
e.Handled =True Else
e.Handled =False End If End Sub
Here's the code example to make the combobox readonly via code:
Note: This works similiarly to tooltips...
The best solution I have seen is to disable the box only for the short moment when it is entered.
That will make it behave exactly the same as if it was read only.
- Proposed as answer by JP14 Wednesday, February 25, 2009 3:42 PM
The Code you provided Seems to work great for locking a combo box.
however it doesn't seem to unlock the combobox. am I missing something?
By the way kudo's for the best solution I have seen so far to this Fiasco by microsoft in eliminating the Locked(readonly) selection from comboboxes.
i'm not sure what we are trying to do here. Why do we want to make the combo box read only? If We just want the users to only input values from the combo box items only, setting the DropDownStyle to DropDownList will do the job. Why do we need to write a bunch of code? Please correct me if I'm missing something here.
Cannot stop learning.
Here's an example of when the "Locked" property of VB6/VBA was useful:
Imagine you have a form populated with textboxes, comboboxes etc. You want this form to be presented to the user in "Read-only" mode when a record is first loaded from data. Then, if the user clicks an "Edit" button on the form, the controls become "Read-Write"; when they click a "Save" button, the data is saved and the controls revert to being "Read-only".
Without a "Locked" property, this kind of user interaction becomes more difficult. In the case of comboboxes, you don't want the user to be able to change the selected item unless they are in "Read-Write" mode.
There are many reasons why one would want a ComboBox to be readOnly... Two of those are:1) If a ComboBox is readonly the user is still able to select the text within the comboBox so that they may select/copy text.2)You may want to allow the user to select the ContextMenu for the ComboBox.Both of these options are not available if the ComboBox is disabled... Why Microsoft would not provide a ReadOnly property is beyond me... what a pain in the a$$.
Some really good answers in here...one that I used that's really simple is to train your users to not type in comboboxes!
On the KeyDown event for your combo box, give them a message to choose one of the items and remove whatever text they typed (which will only be one letter...)
Private Sub ValidateDropDownSelection(ByVal cmb As ComboBox) Dim s As String s = cmb.Text MsgBox("Hey User! Please choose an item from the Drop Down list", MsgBoxStyle.OkOnly) cmb.Text = s End Sub
Private Sub cmbCG_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles cmbCG.KeyDown ValidateDropDownSelection(cmbCG) End Sub
This works for me (sort of on the same theme as Sharp Tea):
void comboBox_Enter(object sender, EventArgs e)
this.SelectNextControl(comboBox, true, true, false, true);
You may want to also set the BackColor property to match a ReadOnly TextBox's BackColor for consistency.
i want to make the combo box readonly
what should i do?
hi every one :)
i have Idea:
Public Class frmRegister
Public s As String = ""
Private Sub frmRegister_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim d As DataSet = classFun.viewofalluser
BindingSource1.DataSource = d.Tables(0)
ComboBox1.DataSource = BindingSource1
ComboBox1.ValueMember = "uid"
ComboBox1.DisplayMember = "fullname"
Private Sub ComboBox1_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.GotFocus
Private Sub ComboBox1_TextUpdate(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.TextUpdate
ComboBox1.Text = s
MessageBox.Show("Dont Change !!")
It's not the most elegant way, but the way I solve this, is to make a new ComboBox class, derived from ComboBox, with an List of objects and a boolean indicating if the status is readonly.
Then I've made a method setReadonly, in which I copy all the values currently in Items to List of objects, then I clear all the items, and I add only the previeously SelectedItem. ComboBoxStyle=DropDownList, so the effect of this, is that no other value can be selected, because there is only one item in the list.
When setReadonly is called with false, I again clear the items, fill it with all the items in the List of object, and make SelectedItem the only value previously in the ComboBox.
Hello People, you've done a lot of code :D
My method for read-only combo-box:
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
e.KeyChar = (char)0;
best regards :)
- Proposed as answer by Levent Mahan Friday, December 24, 2010 2:09 PM
This has been fixed in 2010, however if you are still running 2008 or earlier, implement this code after double clicking the combo box. (Visual studio auto-creates a function for you)
private void cboRTD_Units_SelectedIndexChanged(object sender, EventArgs e)
cboRTD_Units.Enabled = false;
cboRTD_Units.Enabled = true;
That's it... works like a charm! GL
Not sure where it is fixed in 2010 as the way I see the issue is to not allow the user to change a combo box selection yet keep the same look and feel as the original item.
Without overwriting the control I created a boolean that is global to the page. Then a second variable to save the selected value. On form load set the selected value variable. Then set the read only variable when needed. In the combo box _SelectedIndexChanged check your read only variable. If it's true, reset the combo box to the original value and exit the sub.
Dim gComboBoxValue As Integer Dim gComboBoxIsReadOnly As Boolean Private Sub frm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load cboComboBox.SelectedValue = SomeValue gComboBoxValue = SomeValue gComboBoxIsReadOnly = True End Sub Private Sub cboComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboComboBox.SelectedIndexChanged IfgComboBoxIsReadOnly Then cboComboBox.SelectedValue = gComboBoxValue Exit Sub End If Exit Sub
- Proposed as answer by billynoise Tuesday, May 31, 2011 2:42 PM
It's been sometime since the question was asked but for those who still need an answer I found the following pretty helpful:
ComboBox1.TabStop = false;
ComboBox1.Enter += new EventHandler(cmbPlatform_Enter);
void ComboBox1_Enter(object sender, EventArgs e)
TabStop is false to make the Tab key behavior normal while the EventHandler should handle the case where the user manually enters the combobox.
for me best answer was this:
Private Sub Combo_gotfocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles ComboBox1.GotFocus If ComboBox1.IsReadOnly Then ComboBox1.IsEnabled = False End If End Sub Private Sub combo_lostfocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles ComboBox1.LostFocus If ComboBox1.IsReadOnly Then ComboBox1.IsEnabled = True End If End Sub
Nothing is Impossible
- Edited by samanSaadat Tuesday, April 24, 2012 6:58 AM miss typing
private void ReadOnlyComboBox_KeyPress(object sender, KeyPressEventArgs e)
e.Handled = true;
very neat. Excellent solution arunavasaha.
p.s. if you need to make it look like readonly textbox you need also to change the color of the combobox, of course