Skip navigation

Author: Jeff Noble

Here is a quick post about how to make a textbox control that keeps the Font color (ForeColor) Black (or any color) when it’s enabled property is set to false. While I was at it, I added a property to force the text in the textbox to be capital letters. You can change that if you don’t need it.

Here is the code to make it work:


[ToolboxBitmap(typeof (TextBox))]
public class ReadableTextBox : TextBox
{
private bool _forceCapitals = true;
private Color _enabledBackColor = Color.Empty;
private Color _disabledBackColor = Color.LightGray;
private Color _disabledForeColor = Color.Black;

public ReadableTextBox()
{
InitializeComponent();

SetEnabledBackColor();
}

private void SetEnabledBackColor()
{
_enabledBackColor = BackColor;
}

[Browsable(true)]
[DefaultValue(true)]
[Category("Appearance")]
public bool ForceCapitals
{
get { return _forceCapitals; }
set { _forceCapitals = value; }
}

[Browsable(true)]
[Category("Appearance")]
public Color DisabledBackColor
{
get { return _disabledBackColor; }
set { _disabledBackColor = value; }
}

[Browsable(true)]
[Category("Appearance")]
public Color DisabledForeColor
{
get { return _disabledForeColor; }
set { _disabledForeColor = value; }
}

private void InitializeComponent()
{
SuspendLayout();
//
// CallCenterTextBox
//

ResumeLayout(false);
}

protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);

if (_forceCapitals)
{
// Reset the current char to an upper case char.
e.KeyChar = char.Parse(e.KeyChar.ToString().ToUpper());
}
}

public new bool Enabled
{
get { return base.Enabled; }
set
{
base.Enabled = value;
// Turning this UserPaint on causes OnPaint to be called.
// It’s only called when Enabled is false.
SetStyle(ControlStyles.UserPaint, !value);

if (value)
{
BackColor = _enabledBackColor;
}
else
{
BackColor = _disabledBackColor;
}
}
}

protected override void OnPaint(PaintEventArgs e)
{
// Draw the normal textbox
base.OnPaint(e);
// Turn on anti-aliasing for the text, otherwise it looks jagged.
e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
// Draw the text in the box as an image. This is ok, because we ONLY
// call OnPaint when the textbox is disabled.

e.Graphics.DrawString(Text, Font, new SolidBrush(_disabledForeColor), -1, 1);
}
}

That’s It! Enjoy

-Savij

Advertisement

3 Comments

  1. For some reason, when enabled the font is not picked up properly, and uses a different font as a result. I worked around this by setting the font through SendMessage:

    [DllImport("user32.dll")]
    public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, bool lParam);

    private const int WM_SETFONT = 0×0030;

    protected override void OnHandleCreated(EventArgs e) {
    base.OnHandleCreated(e);

    SendMessage(Handle, WM_SETFONT, Font.ToHfont(), true);
    }

  2. Thanks for the code. However setting a Enabled property will not work when using a base class reference, because it is shadowed. You could override OnEnabledChanged method instead. It seems to work perfectly in my scenario. Thanks

  3. thanks very much . your code so good .


Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.