Is it possible to make a combobox Readonly with .Net 1.1

I have looked around and seen a few other people have asked this question,
but the answers have misunderstood the question.

By Readonly, I mean as in the Readonly property for a Textbox

1) You should still be able to highlight and copy text
2) The foreground and background colours should remain unchanged
3) Maybe still allow the dropdown, but different values cannot be selected
4) The current text cannot be changed in any way.

I don't care how complicated it is to do, but I really need to be able to
achieve this.

Chris

Re: Readonly Combobox by Joel

Joel
Fri May 20 13:58:12 CDT 2005

"Chris Austin" <c.austin@bigfoot.com> wrote in
news:#Cqa4nVXFHA.2420@TK2MSFTNGP12.phx.gbl:

> I don't care how complicated it is to do, but I really need to be able
> to achieve this.

Write a new control? Maybe if you inherit from MS's combobox you can
override some methods to achieve what you want.

Re: Readonly Combobox by Bruce

Bruce
Fri May 20 18:56:13 CDT 2005

Here is my version. You can remove the autocompletion stuff, as it has
a minor problem, but the read-only part seems to work well.

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace MyControls
{
/// <summary>
/// A combo box that offers a <c>ReadOnly</c> property that
/// will display the currently selected item clearly but not
/// allow the user to change it, and moves the selection
/// down the list as the user types the text of an entry.
/// </summary>
public class ComboBoxWithAutocompletionReadOnly :
System.Windows.Forms.ComboBox
{
#region Private members

private bool ro;
private Color roBackColor;
private Color roForeColor;
private Color backColorSave;
private Color foreColorSave;
private ComboBoxStyle dropDownStyleSave;
private ContextMenu contextMenuSave;

#endregion

#region Constructor

/// <summary>
/// Creates a new combo box with a <c>null</c> items
collection,
/// and the default display member of <c>"Description"</c>.
/// </summary>
public ComboBoxWithAutocompletionReadOnly()
{
this.ro = false;
this.roBackColor = SystemColors.Control;
this.roForeColor = SystemColors.WindowText;
}

#endregion

#region Static constructor

static ComboBoxWithAutocompletionReadOnly()
{

Agama.AgamaRegistry.Reg.AddControlSerialization(typeof(ComboBoxWithAutocompletionReadOnly),
null, null, false);
}

#endregion

#region Public properties

/// <summary>
/// Sets the combo box so that it still has the standard
/// (enabled) appearance, but it cannot be manipulated by the
/// user.
/// </summary>
/// <value><c>true</c> if the user should not be allowed to
/// change the currently selected item in the combo box,
<c>false</c> if the user should
/// be able to change the combo box contents.</value>
[Description("Controls whether the user can change the combo
box state"), Category("Behavior"), DefaultValue(false)]
public bool ReadOnly
{
get { return this.ro; }
set
{
if (this.ro != value)
{
this.ro = value;
if (this.ReadOnly)
{
this.backColorSave = base.BackColor;
this.foreColorSave = base.ForeColor;
this.dropDownStyleSave = base.DropDownStyle;
this.contextMenuSave = base.ContextMenu;

base.BackColor = this.roBackColor;
base.ForeColor = this.roForeColor;
base.DropDownStyle = ComboBoxStyle.Simple;
base.ContextMenu = new ContextMenu();
}
else
{
base.BackColor = this.backColorSave;
base.ForeColor = this.foreColorSave;
base.DropDownStyle = this.dropDownStyleSave;
base.ContextMenu = this.contextMenuSave;
}
}
}
}

/// <summary>
/// Gets or sets a value specifying the style of the combo box.
/// This property replaces the <see
cref="ComboBox.DropDownStyle"/> property.
/// </summary>
new public ComboBoxStyle DropDownStyle
{
get { return base.DropDownStyle; }
set
{
if (this.ReadOnly)
{
this.dropDownStyleSave = value;
}
else
{
base.DropDownStyle = value;
}
}
}

/// <summary>
/// Gets or sets the shortcut menu associated with the control.
/// This property overrides the <see
cref="Control.ContextMenu"/> property.
/// </summary>
public override ContextMenu ContextMenu
{
get { return base.ContextMenu; }
set
{
if (this.ReadOnly)
{
this.contextMenuSave = value;
}
else
{
base.ContextMenu = value;
}
}
}

/// <summary>
/// Gets or sets the background color for the combo box.
/// This property overrides the <see cref="Control.BackColor"/>
property.
/// </summary>
public override Color BackColor
{
get { return base.BackColor; }
set
{
if (this.ReadOnly)
{
this.backColorSave = value;
}
else
{
base.BackColor = value;
}
}
}

/// <summary>
/// Gets or sets the foreground color for the combo box.
/// This property overrides the <see cref="Control.ForeColor"/>
property.
/// </summary>
public override Color ForeColor
{
get { return base.ForeColor; }
set
{
if (this.ReadOnly)
{
this.foreColorSave = value;
}
else
{
base.ForeColor = value;
}
}
}

#endregion

#region Methods for implementing auto-completion and read-only

/// <summary>
/// This method provides "auto-complete" functionality for the
/// combo box. As the user types characters in the combo box,
/// the box searches down the list of available items and
/// offers the user an auto-complete for the stock code. The
/// box also moves the currently selected item down to the
first
/// item that begins with the text the user typed.
/// </summary>
/// <param name="e">Further details about the key-up event,
/// including which key was pressed.</param>
protected override void OnKeyUp(KeyEventArgs e)
{
if (this.ro)
{
e.Handled = true;
}
else
{
base.OnKeyUp (e);

switch (e.KeyCode)
{
case Keys.Left:
case Keys.Right:
case Keys.Up:
case Keys.Down:
case Keys.Tab:
return;

default:
break;
}

if (this.DropDownStyle != ComboBoxStyle.DropDownList &&
this.Enabled)
{
int insertionPointIndex = this.SelectionStart;
int firstMatchingItemIndex =
this.FindString(this.Text.Substring(0, insertionPointIndex));
if (firstMatchingItemIndex > 0)
{
this.SelectedIndex = firstMatchingItemIndex;
this.SelectionStart = insertionPointIndex;
this.SelectionLength = this.Text.Length;
}
}
}
}

/// <summary>
/// This method throws away keypresses in "read-only" mode,
preventing
/// the user from interacting with the control.
/// </summary>
/// <param name="e">Further information about the key down
event.</param>
protected override void OnKeyDown(KeyEventArgs e)
{
if (this.ReadOnly)
{
e.Handled = true;
}
else
{
base.OnKeyDown (e);
}
}

/// <summary>
/// This method throws away keypresses in "read-only" mode,
preventing
/// the user from interacting with the control.
/// </summary>
/// <param name="e">Further information about the key press
event.</param>
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (this.ReadOnly)
{
e.Handled = true;
}
else
{
base.OnKeyPress (e);
}
}

#endregion
}
}


Re: Readonly Combobox by Chris

Chris
Sat May 21 04:52:15 CDT 2005

Thanks for that, it is easier than I thought it would be.

Chris

"Bruce Wood" <brucewood@canada.com> wrote in message
news:1116633373.106895.268310@g43g2000cwa.googlegroups.com...
> Here is my version. You can remove the autocompletion stuff, as it has
> a minor problem, but the read-only part seems to work well.
>
> using System;
> using System.ComponentModel;
> using System.Drawing;
> using System.Windows.Forms;
>
> namespace MyControls
> {
> /// <summary>
> /// A combo box that offers a <c>ReadOnly</c> property that
> /// will display the currently selected item clearly but not
> /// allow the user to change it, and moves the selection
> /// down the list as the user types the text of an entry.
> /// </summary>
> public class ComboBoxWithAutocompletionReadOnly :
> System.Windows.Forms.ComboBox
> {
> #region Private members
>
> private bool ro;
> private Color roBackColor;
> private Color roForeColor;
> private Color backColorSave;
> private Color foreColorSave;
> private ComboBoxStyle dropDownStyleSave;
> private ContextMenu contextMenuSave;
>
> #endregion
>
> #region Constructor
>
> /// <summary>
> /// Creates a new combo box with a <c>null</c> items
> collection,
> /// and the default display member of <c>"Description"</c>.
> /// </summary>
> public ComboBoxWithAutocompletionReadOnly()
> {
> this.ro = false;
> this.roBackColor = SystemColors.Control;
> this.roForeColor = SystemColors.WindowText;
> }
>
> #endregion
>
> #region Static constructor
>
> static ComboBoxWithAutocompletionReadOnly()
> {
>
>
Agama.AgamaRegistry.Reg.AddControlSerialization(typeof(ComboBoxWithAutocompl
etionReadOnly),
> null, null, false);
> }
>
> #endregion
>
> #region Public properties
>
> /// <summary>
> /// Sets the combo box so that it still has the standard
> /// (enabled) appearance, but it cannot be manipulated by the
> /// user.
> /// </summary>
> /// <value><c>true</c> if the user should not be allowed to
> /// change the currently selected item in the combo box,
> <c>false</c> if the user should
> /// be able to change the combo box contents.</value>
> [Description("Controls whether the user can change the combo
> box state"), Category("Behavior"), DefaultValue(false)]
> public bool ReadOnly
> {
> get { return this.ro; }
> set
> {
> if (this.ro != value)
> {
> this.ro = value;
> if (this.ReadOnly)
> {
> this.backColorSave = base.BackColor;
> this.foreColorSave = base.ForeColor;
> this.dropDownStyleSave = base.DropDownStyle;
> this.contextMenuSave = base.ContextMenu;
>
> base.BackColor = this.roBackColor;
> base.ForeColor = this.roForeColor;
> base.DropDownStyle = ComboBoxStyle.Simple;
> base.ContextMenu = new ContextMenu();
> }
> else
> {
> base.BackColor = this.backColorSave;
> base.ForeColor = this.foreColorSave;
> base.DropDownStyle = this.dropDownStyleSave;
> base.ContextMenu = this.contextMenuSave;
> }
> }
> }
> }
>
> /// <summary>
> /// Gets or sets a value specifying the style of the combo box.
> /// This property replaces the <see
> cref="ComboBox.DropDownStyle"/> property.
> /// </summary>
> new public ComboBoxStyle DropDownStyle
> {
> get { return base.DropDownStyle; }
> set
> {
> if (this.ReadOnly)
> {
> this.dropDownStyleSave = value;
> }
> else
> {
> base.DropDownStyle = value;
> }
> }
> }
>
> /// <summary>
> /// Gets or sets the shortcut menu associated with the control.
> /// This property overrides the <see
> cref="Control.ContextMenu"/> property.
> /// </summary>
> public override ContextMenu ContextMenu
> {
> get { return base.ContextMenu; }
> set
> {
> if (this.ReadOnly)
> {
> this.contextMenuSave = value;
> }
> else
> {
> base.ContextMenu = value;
> }
> }
> }
>
> /// <summary>
> /// Gets or sets the background color for the combo box.
> /// This property overrides the <see cref="Control.BackColor"/>
> property.
> /// </summary>
> public override Color BackColor
> {
> get { return base.BackColor; }
> set
> {
> if (this.ReadOnly)
> {
> this.backColorSave = value;
> }
> else
> {
> base.BackColor = value;
> }
> }
> }
>
> /// <summary>
> /// Gets or sets the foreground color for the combo box.
> /// This property overrides the <see cref="Control.ForeColor"/>
> property.
> /// </summary>
> public override Color ForeColor
> {
> get { return base.ForeColor; }
> set
> {
> if (this.ReadOnly)
> {
> this.foreColorSave = value;
> }
> else
> {
> base.ForeColor = value;
> }
> }
> }
>
> #endregion
>
> #region Methods for implementing auto-completion and read-only
>
> /// <summary>
> /// This method provides "auto-complete" functionality for the
> /// combo box. As the user types characters in the combo box,
> /// the box searches down the list of available items and
> /// offers the user an auto-complete for the stock code. The
> /// box also moves the currently selected item down to the
> first
> /// item that begins with the text the user typed.
> /// </summary>
> /// <param name="e">Further details about the key-up event,
> /// including which key was pressed.</param>
> protected override void OnKeyUp(KeyEventArgs e)
> {
> if (this.ro)
> {
> e.Handled = true;
> }
> else
> {
> base.OnKeyUp (e);
>
> switch (e.KeyCode)
> {
> case Keys.Left:
> case Keys.Right:
> case Keys.Up:
> case Keys.Down:
> case Keys.Tab:
> return;
>
> default:
> break;
> }
>
> if (this.DropDownStyle != ComboBoxStyle.DropDownList &&
> this.Enabled)
> {
> int insertionPointIndex = this.SelectionStart;
> int firstMatchingItemIndex =
> this.FindString(this.Text.Substring(0, insertionPointIndex));
> if (firstMatchingItemIndex > 0)
> {
> this.SelectedIndex = firstMatchingItemIndex;
> this.SelectionStart = insertionPointIndex;
> this.SelectionLength = this.Text.Length;
> }
> }
> }
> }
>
> /// <summary>
> /// This method throws away keypresses in "read-only" mode,
> preventing
> /// the user from interacting with the control.
> /// </summary>
> /// <param name="e">Further information about the key down
> event.</param>
> protected override void OnKeyDown(KeyEventArgs e)
> {
> if (this.ReadOnly)
> {
> e.Handled = true;
> }
> else
> {
> base.OnKeyDown (e);
> }
> }
>
> /// <summary>
> /// This method throws away keypresses in "read-only" mode,
> preventing
> /// the user from interacting with the control.
> /// </summary>
> /// <param name="e">Further information about the key press
> event.</param>
> protected override void OnKeyPress(KeyPressEventArgs e)
> {
> if (this.ReadOnly)
> {
> e.Handled = true;
> }
> else
> {
> base.OnKeyPress (e);
> }
> }
>
> #endregion
> }
> }
>