Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Currency-Masked TextBox from TextBox Class

0.00/5 (No votes)
7 Sep 2011 2  
This is an useful control that masks the input text with currency symbol and thousands and decimals separators.

Introduction

In some applications we need to show the input text in a TextBox with some mask, like, for example, a currency mask to make it more easy to read and understand. In my case, I needed to put text, and additionally, the currency symbol, once the text was written. To do that, I decided to develop a control that inherits from the original TextBox control and implements some new members to allow the control to validate and show the input text with the currency mask we need.

Background

Here is a brief explanation...

TextBox (System.Windows.Forms.TextBox)

The TextBox control is one of the basic and most used controls in WinForms applications that allows the user to input text to interact with the application. It has basics behaviors and members that allow us to use it instantly without having to add anything to the control.

Based on the TextBox control, we are going to develop a TextBox that can mask our input text with currency format, including the currency symbol that we want.

Inheritance

Inheritance is a way to compartmentalize and reuse code by creating objects that have attributes and behaviors that can be based on previously created objects.

Inheritance allows us to work with simple controls like TextBox by taking advantage of their basic behaviors and lets us improve the control by adding new members to control some behaviors that we need to.

In Visual C#, we can write a class definition that inherits from TextBox like this:

public partial class customTextBox : System.Windows.Forms.TextBox

Method overriding

It's a feature that allows a child class to provide a specific implementation of a method that's already provided by its parent class.

As an example, in Visual C#, we can override a method from a parent class by writing:

protected override void OnLostFocus(EventArgs e)
{
    this.Text = formatText();
    base.OnLostFocus(e);
}

Development

Here is an explanation of the code behind the currencyTextBox:

The currencyTextBox control library

The Control Library JRINCCustomControls only contains the currencyTextBox control, and you can add this to your ToolBox in Visual Studio:

...or can reference it as a DLL component directly in your project:

The demo project

The demo project will show you how to implement the currencyTextBox control in a WinForms project, where you can test anything you want about the control.

The code

Now I'll explain the different members I've added to the new textbox and how they work.

In the currencyTextBox class in the JRINCCustomControls project are various custom members that help us achieve the goal of putting the currency-mask to our input text. These are:

Public properties

WorkingText (public string)

It's a read only property that contains our "working text". That means that it contains exactly what the user typed in the TextBox, the text without any mask or formatting.

Definition:

private string _workingText;

public string WorkingText
{
    get { return _workingText; }
    private set { _workingText = value; }
}

PreFix (public string)

It's a public property that can be assigned and retrieved. It must contain the prefix or currency symbol that we want to precede the input text with. If empty, no prefix is used on the masked text. It can be assigned through the Properties window at design time.

Default value: Empty.

Definition:

private string _preFix;
 
/// <summary>
/// Contains the prefix that preceed the inputted text.
/// </summary>
public string PreFix
{
    get { return _preFix; }
    set { _preFix = value; }
}

ThousandsSeparator (public char)

It's a public property that can be assigned and retrieved. It must contain the separator symbol for thousands that we want our input text to show when masked. If empty, no thousands separator is used on the masked text. It can be assigned through the Properties window at design time.

Default value: ','.

Definition:

private char _thousandsSeparator = ',';

/// <summary>
/// Contains the separator symbol for thousands.
/// </summary>
public char ThousandsSeparator
{
    get { return _thousandsSeparator; }
    set { _thousandsSeparator = value; }
  
}

DecimalsSeparator (public char)

It's a public property that can be assigned and retrieved. It must contain the separator symbol for decimals that we want our input text to show when masked. If empty, no decimal separator is used in the masked text. It can be assigned through the Properties window at design time.

Default value: '.'.

Definition:

private char _decimalsSeparator = '.';

/// <summary>
/// Contains the separator symbol for decimals.
/// </summary>
public char DecimalsSeparator
{
    get { return _decimalsSeparator; }
    set { _decimalsSeparator = value; }
}

DecimalPlaces (public int)

It's a public property that can be assigned and retrieved. It must contain the total places for decimal values that we want our input text to show when masked. Minimum value is 0. It can be assigned through the Properties window at design time.

Default value: 2.

Definition:

private int _decimalPlaces = 2;

/// <summary>
/// Indicates the total places for decimal values.
/// </summary>
public int DecimalPlaces
{
    get { return _decimalPlaces; }
    set { _decimalPlaces = value; }
}

Public methods

formatText (public method) returns string

It formats the entered text with the desired specifications. Returns a string with the masked text.

Definition:

/// <summary>
/// Formats the entered text.
/// </summary>
/// <returns></returns>
public string formatText()
{
    this.WorkingText = this.Text.Replace(
      (_preFix != "") ? _preFix : " ", String.Empty).Replace(
      (_thousandsSeparator.ToString() != "") ? 
        _thousandsSeparator.ToString() : " ", String.Empty).Replace(
      (_decimalsSeparator.ToString() != "") ? 
        _decimalsSeparator.ToString() : " ", String.Empty).Trim();
    int counter = 1;
    int counter2 = 0;
    char[] charArray = this.WorkingText.ToCharArray();
    StringBuilder str = new StringBuilder();

    for (int i = charArray.Length - 1; i >= 0; i--)
    {
        str.Insert(0, charArray.GetValue(i));
        if (this.DecimalPlaces == 0 && counter == 3)
        {
            counter2 = counter;
        }
        
        if (counter == this.DecimalPlaces && i > 0)
        {
            if (_decimalsSeparator != Char.MinValue)
                str.Insert(0, _decimalsSeparator);
            counter2 = counter + 3;
        }
        else if (counter == counter2 && i > 0)
        {
            if (_thousandsSeparator != Char.MinValue)
                str.Insert(0, _thousandsSeparator);
            counter2 = counter + 3;
        }
        counter = ++counter;
    }
    return (this._preFix != "" && str.ToString() != "") ? 
       _preFix + " " + str.ToString() : 
       (str.ToString() != "") ? str.ToString() : "";
}

Protected overridden methods

OnLostFocus (protected override method)

This method allows the currencyTextBox to load the formatted text to the Text property. It executes the formatText method, then proceeds to execute the original implementation of the OnLostFocus method.

Definition:

protected override void OnLostFocus(EventArgs e)
{
    this.Text = formatText();
    base.OnLostFocus(e);
}

OnGotFocus (protected override method)

This method allows the currencyTextBox to load the working text to the Text property. In this state, the control is in edit mode (please refer to the WorkingText property definition above). After this, it proceeds to execute the original implementation of the OnGotFocus method.

Definition:

protected override void OnGotFocus(EventArgs e)
{
    this.Text = this.WorkingText;
    base.OnGotFocus(e);
}

OnKeyPress (protected override method)

This method brings some validation to ensure that the values entered to the TextBox are only numbers. After the validation, it executes the original implementation of the OnKeyPress method.

Definition:

protected override void OnKeyPress(KeyPressEventArgs e)
{
    if (!Char.IsDigit(e.KeyChar))
    {
        if (!(e.KeyChar == Convert.ToChar(Keys.Back)))
            e.Handled = true;
    }
    base.OnKeyPress(e);
}

Conclusion

There are so many characteristics that we can improve about a control like TextBox, and one of the more important things that we can do is always search for a way to improve it and make it more maintainable by adding reusable components like the CurrencyTextBox. I hope it can help you, like it did for me.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here