Click here to Skip to main content
Click here to Skip to main content

A Currency-Masked TextBox from TextBox Class

, 7 Sep 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

JRINC
Software Developer (Senior)
Venezuela Venezuela
No Biography provided

Comments and Discussions

 
QuestionAccounting application - needs to handle negative money amounts (such as debts and liabilities) PinmemberBrian C Hart6-Dec-14 6:08 
QuestionCurrency-Masked TextBox - Good job! PinmemberNanox1126-Dec-13 5:45 
AnswerRe: Currency-Masked TextBox - Good job! PinmemberJRINC26-Dec-13 9:01 
SuggestionSource doesn't match article PinmemberLH40530-Jul-13 6:01 
GeneralRe: Source doesn't match article PinmemberJRINC2-Sep-13 6:11 
QuestionRegional settings values PinmemberBenny Tordrup17-Sep-11 2:20 
AnswerRe: Regional settings values PinmemberJRINC19-Sep-11 3:53 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150224.1 | Last Updated 7 Sep 2011
Article Copyright 2011 by JRINC
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid