Click here to Skip to main content
15,902,817 members
Articles / Desktop Programming / Windows Forms

HintTextBox

Rate me:
Please Sign up or sign in to vote.
3.19/5 (12 votes)
15 May 2007CPOL3 min read 50.5K   649   40   15
Shows inline hint for a textbox. Useful in cases where the UI is small and has to fit many input controls.

Screenshot - HintTextBox_Form.pngScreenshot - HintTextBox_Form_Password.png

Introduction

Very often, we (UI designers) are in situations where we have to capture a large amount of information from the user in a single screen. In such cases, it seems impossible to add enough labels and textboxes in a single form due to space considerations and the dimensions of the form. Nowadays, we see many forms over the internet which solve this problem. The idea being "why not add the label to the textbox itself?" I.e., can't the textbox itself act as the label (caption) and capture User Input at the same time?

This aritcle tries to solve these kind of problems with the use of a custom made control which I have used in many of my commercial applications. Moreover, it is a straight out-of-the-box control with a custom UI Smart Tag Designer, which is very handy.

Background

In one of my applications, I was left with just enough space on the form to accommodate two text boxes. What I thought was why not use the ways similar to Internet web forms and add a textbox which can act as both a textbox as well as a label.

I quickly Googled and found some similar controls which solved my problem. Well, it seemed so,. The control which I used functioned like this:

  1. Embed a Label control in a TextBox.
  2. Toggle the visibility of the Label when it get and loses focus.

This seemed to be a cool trick, but what pushed me to write my own control was, why in God's world should I use a Label when only a string should ideally do the job?

I somehow completed the application and delivered it, but the quest to develop such a control was always rolling in the back of my mind. So there I was, left with an inquisitive mind and a need to develop such a control which I could use across all my applications, and that too with a Smart Tag Designer so as to quickly do the job of preparing the UI.

Control Code

Well, the control code is much simpler than it seems to be, though a little lengthy. You can browse through the source code in the Zip files above.

Idea

  • Add a property of type string and use it to swap with the Text property of base TextBox on getting and losing focus.
  • Use some swap variables to hold the values of the Forecolor and Text properties.

SmartTag Designer

This was a bit tough to configure, but with some initial problems, I found out that the Smart Tags are dependent on Smart Tag UI Designers which are inherited from the System.Windows.Forms.Design.ControlDesigner class present in the System.Design.dll assembly.

Every inherited class should have a DesignerActionListCollection member variable which holds the reference to a class which holds the properties which should be displayed in the SmartTag.

The actual class which contains the properties to display is the one which is inherited from the DesignerActionList class.

Anyways, this is a bit too tricky... here you go with the code:

C#
/////////////////////////////////////////////////////////////////
// Designer for the HintTextBox control with support for a smart 
// tag panel.
// Must add reference to System.Design.dll
/////////////////////////////////////////////////////////////////
[System.Security.Permissions.PermissionSet(
        System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
internal class ColorLabelDesigner : System.Windows.Forms.Design.ControlDesigner
{
    private DesignerActionListCollection actionLists;

    // Use pull model to populate smart tag menu.
    public override DesignerActionListCollection ActionLists
    {
        get
        {
            if (null == actionLists)
            {
                actionLists = new DesignerActionListCollection();
                actionLists.Add(new HintTextBoxDesignerActionList (this.Component));
            }
            return actionLists;
        }
    }
}

//the above class (ColorLabelDesigner )acts as a connector 
//connecting the Control and its Smart Tag Designer UI

internal class HintTextBoxDesignerActionList : DesignerActionList
{
    HintTextBox _BaseControl;
    private DesignerActionUIService designerActionUISvc = null;

    public HintTextBoxDesignerActionList(IComponent component)
        : base(component)
    {
        try
        {
            _BaseControl = (HintTextBox)component;
            this.designerActionUISvc = 
              GetService(typeof(DesignerActionUIService)) as DesignerActionUIService;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    // Helper method to retrieve control properties. Use of 
    // GetProperties enables undo and menu updates to work properly.
    private PropertyDescriptor GetPropertyByName(String propName)
    {
        PropertyDescriptor prop;
        prop = TypeDescriptor.GetProperties(_BaseControl)[propName];
        if (null == prop)
            throw new ArgumentException(
                 "Matching property not found!",
                  propName);
        else
            return prop;
    }

    public bool IsPassword
    {
        get { return _BaseControl.IsPassword; }
        set
        {
            GetPropertyByName("IsPassword").SetValue(_BaseControl, value);
            _BaseControl.Multiline = false;
            this.designerActionUISvc.Refresh(this.Component);
        }
    }

    public bool MultiLine
    {
        get { return _BaseControl.Multiline; }
        set
        {
            GetPropertyByName("Multiline").SetValue(_BaseControl, value);
            _BaseControl.IsPassword = false;
            this.designerActionUISvc.Refresh(this.Component);
        }
    }

    public string Hint
    {
        get { return _BaseControl.Hint; }
        set
        {
            GetPropertyByName("Hint").SetValue(_BaseControl, value);
            this.designerActionUISvc.Refresh(this.Component);
        }
    }

    public string Name
    {
        get { return _BaseControl.Name; }
        set
        {
            GetPropertyByName("Name").SetValue(_BaseControl, value);
            this.designerActionUISvc.Refresh(this.Component);
        }
    }

    public Color HintColor
    {
        get { return _BaseControl.HintColor; }
        set
        {
            GetPropertyByName("HintColor").SetValue(_BaseControl, value);
            this.designerActionUISvc.Refresh(this.Component);
        }
    }

    public Color TextColor
    {
        get { return _BaseControl.TextColor; }
        set
        {
            GetPropertyByName("TextColor").SetValue(_BaseControl, value);
            this.designerActionUISvc.Refresh(this.Component);
        }
    }

    public HorizontalAlignment HintAlignment
    {
        get { return _BaseControl.HintAlignment; }
        set
        {
            GetPropertyByName("HintAlignment").SetValue(_BaseControl, value);
            this.designerActionUISvc.Refresh(this.Component);
        }
    }

    public override DesignerActionItemCollection GetSortedActionItems()
    {
        DesignerActionItemCollection items = new DesignerActionItemCollection();

        //Define static section header entries.
        items.Add(new DesignerActionHeaderItem("Design"));
        items.Add(new DesignerActionHeaderItem("Behaviour"));
        items.Add(new DesignerActionHeaderItem("Appearance"));

        //Boolean property for locking color selections.

        items.Add(new DesignerActionPropertyItem("IsPassword",
                         "Password Field", "Behaviour",
                         "Is it a password field ?"));
       items.Add(new DesignerActionPropertyItem("MultiLine",
                         "MultiLine", "Behaviour",
                         "Multiline Text Field"));
            items.Add(new DesignerActionPropertyItem("HintColor",
                             "Hint Color", "Appearance",
                             "Sets the Hint Text color."));
            items.Add(new DesignerActionPropertyItem("TextColor",
                             "Text Color", "Appearance",
                             "Sets the Text Color."));
            items.Add(new DesignerActionPropertyItem("HintAlignment",
                             "HintAlignment", "Appearance",
                             "Sets the Hint Alignment."));
            //This next method item is also added to the context menu 
            // (as a designer verb).
            
        items.Add(new DesignerActionPropertyItem("Name",
                         "Control Name", "Design",
                         "Sets the Control Name."));
        items.Add(new DesignerActionPropertyItem("Hint",
                        "Hint", "Design",
                        "Sets the Hint text."));

        items.Add(new DesignerActionMethodItem(this,
                             "DefaultColors", "Set Default Colors",
                             "Appearance",
                             "Sets default Hint and Text colors.",
                              true));

        return items;
    }
    public void DefaultColors()
    {
        this._BaseControl.HintColor = Color.Gray;
        this._BaseControl.TextColor = Color.Black;
        this.designerActionUISvc.Refresh(this.Component);
    }

All you now have to do is add the designer type attribute on top of the control class which we have prepared:

C#
[Designer(typeof(ColorLabelDesigner))]
public class HintTextBox
Result

Screenshot - HintTextBox_Designer_3.png

For those who are trying to modify the SmartTag UI, don't forget to add a reference to System.Design.dll found here.

Screenshot - HintTextBox_AddReference.png

Using the Control

To use the control, first drag HintTextBox.dll on the the toolbar (any toolbar) and you should be able to see a control named "HintTextBox".

There you are.. ready to go.. drag and drop it on any form and use it as you like...

Just remember to use the InternalText property to access user input text instead of using the traditional Text property.

Screenshot - HintTextBox_Form_Code1.png

History

  1. Added the HintAlignment property.
  2. Rectified the source code to make the ForeColor property work.
  3. N.B.: New property name: TextColor.

  4. Modified the Smart Tag to add extra properties and categorical support for them.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy implementation Pin
80936-Jun-07 16:30
80936-Jun-07 16:30 
GeneralCant clear programatically Pin
Nikkoli6-Jun-07 11:09
Nikkoli6-Jun-07 11:09 
AnswerRe: Cant clear programatically Pin
samir411806-Jun-07 23:39
samir411806-Jun-07 23:39 
GeneralRe: Cant clear programatically Pin
samir411806-Jun-07 23:44
samir411806-Jun-07 23:44 
oops I forgot to write the usage after that...

private void button2_Click(object sender, EventArgs e)
{
hintTextBox1.InternalText = "";
}


GeneralForeColor doesn't work... Pin
Seishin#17-May-07 23:44
Seishin#17-May-07 23:44 
GeneralRe: ForeColor doesn't work... Pin
samir4118018-May-07 0:04
samir4118018-May-07 0:04 
GeneralRe: ForeColor doesn't work... Pin
samir4118018-May-07 1:50
samir4118018-May-07 1:50 
GeneralGoood Article, awful spelling Pin
J4amieC15-May-07 4:12
J4amieC15-May-07 4:12 
GeneralRe: Goood Article, awful spelling Pin
samir4118015-May-07 4:45
samir4118015-May-07 4:45 
GeneralRe: Goood Article, awful spelling Pin
J4amieC15-May-07 5:34
J4amieC15-May-07 5:34 
AnswerRe: Goood Article, awful spelling Pin
Ravi Bhavnani15-May-07 8:14
professionalRavi Bhavnani15-May-07 8:14 
GeneralNice Pin
The_Mega_ZZTer15-May-07 3:44
The_Mega_ZZTer15-May-07 3:44 
GeneralRe: Nice Pin
samir4118015-May-07 4:10
samir4118015-May-07 4:10 
GeneralRe: Nice Pin
samir4118015-May-07 4:51
samir4118015-May-07 4:51 
GeneralBrilliant Pin
kin3tik15-May-07 3:42
kin3tik15-May-07 3:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.