Cue banners in WinForms

A look at how WinForms text boxes can be extended to have a 'cue banner' (that greyed-out placeholder or explanatory text often seen in text fields).


A popular UI element these days is the 'cue banner' - that greyed-out placeholder or explanatory text you often see in a text field.

An example cue banner on a website

WinForms doesn't offer any out-of-the-box controls that support cue banners.

Luckily for us, there are a few ways to implement one ourselves. The original method I used to recommend was using the Windows API EM_SETCUEBANNER message. However, that got a bit clunky in multi-line controls, and a few other edge-cases. Nowadays, I recommend overriding the WM_PAINT message in the WndProc handler and drawing the cue text ourselves.

See the following example:

/// <summary>
/// Represents a Windows text box control with a cue banner.
/// </summary>
public class CueTextBox : TextBox
{
    /// <summary>
    /// The cue banner text.
    /// </summary>
    private string _cueText;

    /// <summary>
    /// Gets or sets the cue banner text.
    /// </summary>
    public string CueText
    {
        get
        {
            return _cueText;
        }

        set
        {
            _cueText = value;
            Invalidate();
        }
    }

    /// <summary>
    /// Processes Windows messages.
    /// </summary>
    /// <param name="m">A Windows Message object.</param>
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        const int WM_PAINT = 0xF;
        if (m.Msg == WM_PAINT)
        {
            if (!Focused && String.IsNullOrEmpty(Text) && !String.IsNullOrEmpty(CueText))
            {
                using (var graphics = CreateGraphics())
                {
                    TextRenderer.DrawText(
                        dc: graphics,
                        text: CueText,
                        font: Font,
                        bounds: ClientRectangle,
                        foreColor: SystemColors.GrayText,
                        backColor: Enabled ? BackColor : SystemColors.Control,
                        flags: TextFormatFlags.Top | TextFormatFlags.Left);
                }
            }
        }
    }
}

This gives us a lovely little cue banner in WinForms:

An example of our WinForms cue banner

Enjoy!


Posted by Matthew King on 30 November 2013
Permission is granted to use all code snippets under CC BY-SA 3.0 (just like StackOverflow), or the MIT license - your choice!