Click here to Skip to main content
15,886,110 members
Articles / Web Development / ASP.NET
Article

TextBoxEx: A Little Enhanced TextBox

Rate me:
Please Sign up or sign in to vote.
3.77/5 (3 votes)
4 Dec 2008CPOL3 min read 31.2K   274   23   3
Learn how to create a TextBox with ToolTips in-place and OnFocus colors

Introduction

I'm a huge fan of reusable code and for the last 10 years I have created a lot of libraries I have used in my company (mostly on Delphi and C/C++). Now that I'm migrating all my projects to C#/ASP.NET, I'm also rewriting those libraries, including some custom components I always loved.

The most important component for me is actually the TextBox, since most of my work is based on database software that requires several forms to handle data and the idea of always knowing where you are and what you should do on a form is really nice. 

Background

TextBoxEx is an easy-to-use custom control and it tries to make the user aware about the current editing field and display tooltips inside all the other TextBoxes - no need to move the mouse over.

Features

  • ToolTips in-place: The tooltip property is shown inside the control when it doesn't have the focus and unless the user types something else there.
  • You can set the color for the ToolTip text to be used.
  • You can set the colors for the font and for TextBox when the focus is on it.
  • You can link it to a Label, so when it gets the focus, the font-style of this label is set to bold.

textboxex

Using the Code

You can either add the TextBoxEx.cs and TextBoxExEditor.cs to your project or to your Custom Control library that you're creating. Then you just place the TextBoxEx control into your WebForm.

Warning: If you don't know how to use custom control, you must read something about it first. This article doesn't explain how you do it, but Your First ASP.NET Custom Control does. 

How It Works

  1. A JavaScript code handles the onblur and onfocus input control events.
  2. Another JavaScript code is registered to the form onsubmit event so the tooltip text is removed from the unfulfilled TextBoxExes.
  3. When you select a TextBoxEx at design time and go to the Label property, you can see a list of labels available for selection. You can set the link from more than one TextBoxEx to the same Label if it makes sense to you.

Linking to a Label

A special ListBox

If you use the DropDownControl passing a list box as parameter, it will be shown OK, but it will close only when you press ENTER, so I made a ListBox class that gets a IWindowsFormsEditorService as parameter in the constructor and subscribe to the ListBox OnClick event and close it.

C#
/// <summary>
/// This class shows a listbox with the values hide it when it's clicked
/// </summary>
public class ListBoxEditor : System.Windows.Forms.ListBox
{
    IWindowsFormsEditorService SRV = null;

    private ListBoxEditor() { }
    internal ListBoxEditor(IWindowsFormsEditorService srv)
    {
        SRV = srv;
        Sorted = true;
        this.Click += new EventHandler(ListBoxEditor_Click);
    }

    void ListBoxEditor_Click(object sender, EventArgs e)
    {
        if (SRV != null)
        SRV.CloseDropDown();
    }
}

Listing the Labels Available at Design-Time

The IReferenceService provides several methods that allow you to get instances of all controls available at design-time.

C#
public override object EditValue(ITypeDescriptorContext context, 
IServiceProvider provider, object value)
{
    IWindowsFormsEditorService srv = null;
    if (provider != null)
        srv = (IWindowsFormsEditorService)provider.GetService(
              typeof(IWindowsFormsEditorService));
    if (srv != null)
    {
        ListBoxEditor lb = new ListBoxEditor(srv);
        lb.Sorted = true;
        IReferenceService irs = 
             (IReferenceService)provider.GetService(
        typeof(IReferenceService));
        if (irs != null)
        {
            object[] os = irs.GetReferences(typeof(Label));
            foreach (object o in os)
            {
                Label wc = (Label)o;
                lb.Items.Add(wc.ID);
            }
        }
        lb.SelectedIndex = lb.Items.IndexOf((string)value);
        srv.DropDownControl(lb);
        return lb.Text;
    }

    return value;
}

textboxex2.JPG

Client-side Programming

The JavaScript part was by far the easiest part and the integration provided by ASP.NET is great!!!

I just had to create the JavaScript code, register it and then add the attributes to the control. But it's really important to remember that I had also to subscribe to the onsubmit form event to deal with unfulfilled TextBoxEx controls, because I had to clear their values so the hints wouldn't be sent instead of the empty values.

C#
private void RegisterScript()
{
#region Main Script Code
string script = @"
<script type='text/javascript'>
function JRTextBox_ChangeStyles_Enter(id, hint, backcolor, fontcolor)
{
    if(id.value==hint)id.value='';
    id.style.color = fontcolor;
    id.style.backgroundColor = backcolor;
}

function JRTextBox_ChangeStyles_Enter_Label(label, id, hint, backcolor, fontcolor)
{
    JRTextBox_ChangeStyles_Enter(id, hint, backcolor, fontcolor);
    elem = document.getElementById(label);
    if(elem!=null)
    {
        elem.style.fontWeight = 'bold';
    }
}

function JRTextBox_ChangeStyles_Exit(id, hint, hintfontcolor, backcolor, fontcolor)
{
    if(id.value=='')
    {
        id.value=hint;
        id.style.color = hintfontcolor;
        id.style.backgroundColor = backcolor;
    }
    else
    {
        id.style.color = fontcolor;
        id.style.backgroundColor = backcolor;
    }
}

function JRTextBox_ChangeStyles_Exit_Label(label, id, hint, 
hintfontcolor, backcolor, fontcolor)
{
    JRTextBox_ChangeStyles_Exit(id, hint, hintfontcolor, backcolor, fontcolor);
    elem = document.getElementById(label);
    if(elem!=null)
    {
        elem.style.fontWeight = 'normal';
    }
}

function JRTextBox_ValidateHint(id, hint)
{
    elem = document.getElementById(id);
    if(elem!=null)
    {
        if(elem.value==hint)elem.value='';
    }
}
</script>";
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), 
                ScriptName, script);
            #endregion

            #region OnSubmit
            // register the script to avoid the hint to be posted
            Page.ClientScript.RegisterOnSubmitStatement(this.GetType(),
                string.Format("{0}_{1}_OnSubmit", ScriptName, ID),
                string.Format("JRTextBox_ValidateHint('{0}','{1}');\n", 
                ClientID, ToolTip)
                );
            #endregion
        }        protected override void Render(HtmlTextWriter output)
        {
            //
            if (!string.IsNullOrEmpty(Label))
            {
                LabelID = GetID(Page.Controls);
            }

            // inner methods
            if (!string.IsNullOrEmpty(LabelID))
            {
                output.AddAttribute("onblur",
                    "JRTextBox_ChangeStyles_Exit_Label('" +
                    LabelID + "'," + ClientID + ",'" + ToolTip + "','" +
                    ColorTranslator.ToHtml(FontColorToolTip) + "','" +
                    ColorTranslator.ToHtml(BackColor) + "','" +
                    ColorTranslator.ToHtml(OldForeColor) +
                    "');"
                    );
                output.AddAttribute("onfocus",
                    "JRTextBox_ChangeStyles_Enter_Label('" +
                    LabelID + "'," + ClientID + ",'" + ToolTip + "','" +
                    ColorTranslator.ToHtml(BackColorEnter) + "','" +
                    ColorTranslator.ToHtml(FontColorEnter) +
                    "');"
                    );
            }
            else
            {
                output.AddAttribute("onblur",
                    "JRTextBox_ChangeStyles_Exit(" +
                    ClientID + ",'" + ToolTip + "'," +
                    ColorTranslator.ToHtml(FontColorToolTip) + "," +
                    ColorTranslator.ToHtml(BackColor) + "," +
                    ColorTranslator.ToHtml(OldForeColor) +
                    ");"
                    );
                output.AddAttribute("onfocus",
                    "JRTextBox_ChangeStyles_Enter(" +
                    ClientID + ",'" + ToolTip + "'," +
                    ColorTranslator.ToHtml(BackColorEnter) + "," +
                    ColorTranslator.ToHtml(FontColorEnter) +
                    ");"
                    );
            }
            // calls the base method
            base.Render(output);
        }

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

            OldForeColor = ForeColor;
            if (string.IsNullOrEmpty(Text))
            {
                Text = ToolTip;
                ForeColor = FontColorToolTip;
            }

            // script codes
            if (!Page.ClientScript.IsClientScriptBlockRegistered(ScriptName))
                RegisterScript();
        }

Suggestions

  • Create some kind of font-style property, so you can set most font attributes for the onfocus event (for the Label and for the TextBoxEx). The way it is now, it works for me, but someone may want to change the Label style to italic and blue, instead of just making it bold.

History

  • December 04, 2008 - Initial release
  • December 05, 2008 - I pasted and explained come of the important code here as suggested

License

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


Written By
Team Leader JR Softwares
Brazil Brazil
Working for about 10 years with Delphi/C/C++/Java technology and now migrating all Delphi products I have made to C# and ASP.NET.

Comments and Discussions

 
GeneralYou need to show some code so we know how it works Pin
Sacha Barber5-Dec-08 2:43
Sacha Barber5-Dec-08 2:43 
GeneralRe: You need to show some code so we know how it works Pin
Dirso5-Dec-08 5:45
Dirso5-Dec-08 5:45 
GeneralRe: You need to show some code so we know how it works Pin
Sacha Barber5-Dec-08 21:55
Sacha Barber5-Dec-08 21:55 

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.