-2

This may be a vague question but I am trying to find a function that sets all text boxes on a form to a currency format. On my form I have some preset boxes but many will be dynamic with the push of a button. The information in these text boxes will come from Access. I have a sample function for clearing text boxes, I'm curious if there is something similar for what I'm asking.

 private void txtMaxDiscount_TextChanged(object sender, EventArgs e)
    {
        double amount = 0.0d;
        if (double.TryParse(txtMaxDiscount.Text, NumberStyles.Currency, null, out amount))
        {
            txtMaxDiscount.Text = amount.ToString("C");
        }
    }
Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
CamlCase
  • 191
  • 2
  • 2
  • 15
  • Very hard to guess why you are looking for something different. By far the simplest way is `new Form2()`. If that makes you app terminate then [use this](http://stackoverflow.com/a/10769349/17034). – Hans Passant Feb 07 '16 at 17:45
  • Well, don't focus on the sample code that I inserted for the clear all***, that's not what I want to achieve. I am actually looking for a way to " set all boxes to a currency format ". I am trying to avoid using a million lines of code for this achievement. – CamlCase Feb 07 '16 at 17:48
  • 2
    Don't post sample code that has nothing to do with the question. A TextBox does not have a "currency format". It is your code that converts data to a specific text format. We can't see it. – Hans Passant Feb 07 '16 at 17:50
  • I don't think you can set format without entering any value. You'll have to set the format when you have the value you want to input. You could make a function that changes the format after you input and call it everytime you lose focus from a text box. – gallickgunner Feb 07 '16 at 17:51
  • Here is the code I am using now for " 1 " text box. I am trying to figure out If I can create a "package" deal for many instead of just one. I inserted the piece from my source above. The previous code was for example only. – CamlCase Feb 07 '16 at 17:53
  • So you mean when the user, say, presses a button, you want to find every textbox on the form, and if it contains a number then format it as a currency? Or have a reusable textbox component that when the users types in it, it formats just that box as a currency? – Rhumborl Feb 07 '16 at 17:58
  • Well, somewhat. Here is my operation : 1) a button is pressed and information is transferred from Access to the user form, when this information arrives it is in a format of 5.5, I need it to show in the text box as $5.50. With the code above it does work for each text box that I apply this piece of code to. I have many, many boxes. So the " text_changed " seems to make more sense to me. – CamlCase Feb 07 '16 at 18:04
  • You could simply hook the same method, e.g. `txtMaxDiscount_TextChanged`, to multiple textboxes, so they all use the same one. In the `TextChanged` event handler box in Visual Studio, just paste in the method name. You be able to select multiple textboxes and do this in one go – Rhumborl Feb 07 '16 at 18:06

2 Answers2

0

You could create your own control, per this stack overflow post. You can create your own textbox, derived off of the base control. Therefore, you can designate your own data source and formatting, but also can extend upon the control, with other capabilities. Likewise, this will allow for re-use, without repetition.

public class TextBoxEx : TextBox
{
    public string Format { get; set; }

    private object datasource = new object();
    public object Datasource
    {
        get { return datasource; }
        set 
        {
            datasource = value;
            if (datasource == null)
                base.Text = string.Empty;
            else if(string.IsNullOrWhiteSpace(Format))
                base.Text = datasource.ToString();
            else
                base.Text = string.Format("{0:"+ Format + "}",datasource);
        }
    }
}

Usage:

   textbox.Format = "c";
   textbox.Datasource = DataSet.DataView[0].Amount;
Community
  • 1
  • 1
Quinn Johns
  • 376
  • 4
  • 16
0

I think I understand what you are asking for. You are looking to automatically format all text boxes on a form, including new text boxes which are dynamically added.

To achieve this, the first step is to set up a generic event handler when focus is lost to any currency text box:

void OnCurrencyTextBoxLeave(object sender, EventArgs e)
{
    if (sender is TextBox)
    {
        decimal value;
        var textBox = (TextBox)sender;
        if (decimal.TryParse(textBox.Text, out value))
        {
            textBox.Text = value.ToString("C");
        }
        else textBox.Text = string.Empty;
    }
}

Then we can add two functions to the form which will subscribe text boxes to this event handler to automatically take care of the formatting. The first one is called only once when the form is created, and takes care of any text boxes added at design time (or when the form is first created):

private void SubscribeCurrencyTextboxes(Control container)
{
    foreach (Control control in container.Controls)
    {
        if (!(control is TextBox)) continue;
        ((TextBox)control).Leave += OnCurrencyTextBoxLeave;
    }
}

To use this function we can simply call it within the form load event, or override OnLoad as follows:

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

We should add one more function to subscribe to dynamically created text boxes at run time:

private void SubscribeCurrencyTextboxes(params TextBox[] textBoxes)
{
    foreach (var textBox in textBoxes) textBox.Leave += OnCurrencyTextBoxLeave;
}

Now, when you dynamically create your text boxes, add another call to SubscribeCurrencyTextboxes and supply it with a list of instances, such as:

SubscribeCurrencyTextboxes(textBox1, textBox2, ... textBox20);


When the user leaves each text box on the form, it will be formatted for currency automatically!


Another way (perhaps a better way) to achieve the same result -- especially if you require re-usability of this behavior -- would be to inherit from TextBox and extend it. (Please see other answers here to your question suggesting the same.) We could call the inherited control CurrencyTextBox and instead of dynamically adding ordinary text boxes to your form, you could add text boxes of this custom type.

To get you started, you could declare:

public class CurrencyTextBox : TextBox
{
    // Apply currency formatting when text is set from code:
    public override string Text
    {
        get { return base.Text; }
        set
        {
            base.Text = Format(RemoveCurrencyFormatting(value));
        }
    }

    // Expose decimal currency value to code:
    public decimal Value
    {
        get { return this.value; }
        set { this.value = value; }
    }

    private decimal value = 0m;

    // Remove currency formatting dollar signs and commas on focus:
    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        this.Text = RemoveCurrencyFormatting(this.Text);
        this.SelectAll();
    }

    // Apply currency formatting when focus is lost:
    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        Format(this.Text);
    }

    // Perform actual formatting:
    private string Format(string text)
    {
        if (!decimal.TryParse(text, out this.value))
        {
            return value.ToString("C");
        }
        else return string.Empty;
    }

    // Remove currency formatting dollar signs and commas:
    private string RemoveCurrencyFormatting(string value)
    {
        if (!string.IsNullOrEmpty(value))
        {
            return value
                .Replace(NumberFormatInfo.CurrentInfo.CurrencySymbol, string.Empty)
                .Replace(NumberFormatInfo.CurrentInfo.NumberGroupSeparator, string.Empty);
        }
        else return string.Empty;
    }
}

This example makes use of NumberFormatInfo to take care of currency symbols (such as dollar signs and thousands separator commas here in North America) which could trip up any type of currency formatting. Be sure to add a using directive to System.Globalization:

using System.Globalization;

You can find out more information about NumberFormatInfo on this MSDN page.

Lemonseed
  • 1,644
  • 1
  • 15
  • 29
  • Now would this show the new format when the data arrives from Access or ?. After running this it doesn't give errors but it doesn't apply what I'm trying to do. I need to look at it and see if I can adjust anything. Just making sure I'm not missing any steps on this. – CamlCase Feb 07 '16 at 18:52
  • Now in this code sample from above : SubscribeCurrencyTextboxes(textBox1, textBox2, ... textBox20); I may have up to 80 text boxes on a single form run. Would I need to put all of that in ? – CamlCase Feb 07 '16 at 18:56
  • Since I have marked the argument with the `params` keyword, you can pass an array into the function. So the solution would probably be to create an array (or a `List`) as you are dynamically creating your textboxes, and pass this to the `SubscribeCurrencyTextboxes` function. That way you will not have to individually list all 80-odd text boxes explicitly. (tip: If you use a List object, be sure to call `.ToArray()` when passing to convert to `TextBox[]`.) – Lemonseed Feb 07 '16 at 19:03