Подтвердить текстовое поле валюты

Я использую WinForm. У меня есть текстовое поле и кнопка.

Цель: кнопка должна проверять, является ли текстовое поле валютным форматом. Если текстовое поле является валютным форматом, сообщение должно отображать формат валюты. Если нет, тогда сообщение должно отображать ошибочный формат ошибки.

Пример формата валюты:

$1,234.00

$12,345.00

$123,000.00

$1,00

Update:

Это то, что у меня было, но это неправильно.

    Private void button3_Click(object sender, EventArgs e)
    {    
        currencyTextbox = Convert.ToString(textBox4.Text);

        string money = currencyTextbox;

        string s = currencyTextbox;
        float f;
        if (float.TryParse(s, NumberStyles.AllowCurrencySymbol 
            | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, 
            CultureInfo.GetCultureInfo("en-US"), out f))
        {
            MessageBox.Show("Ok");
        }
        else
        {
            MessageBox.Show("Wrong");
        }
     }

Тестовые случаи:

$12.00 - ОК

$12,000 - ОК

$12,3,00 - OK - (Неверно)

$12,3,00 # - Неверно

Ответ 1

Число (decimal в этом случае) не совпадает с его строковым представлением (в данном случае валютой). Поэтому вы должны сначала проанализировать ввод с строковой точки зрения (соответствует ли формат?), А затем из числового. Есть несколько способов выполнить анализ за один раз (как предложено в других ответах), хотя они не доставляют вам определения (т.е. Это валюта или нет, понимаются как простые числа).

Пример кода:

private void btn_Click(object sender, EventArgs e)
{
    //Note: ideally, curCulture shouldn't be defined here (but globally or  
    //passed as argument), but otherwise my code would be somehow incomplete.
    CultureInfo curCulture = new CultureInfo("en-US", true);

    bool isOK = false;
    string[] temp = totalTextBox.Text.Trim().Split(new string[] { curCulture.NumberFormat.CurrencySymbol }, StringSplitOptions.None);
    if (temp.Length == 2 && temp[0].Trim().Length == 0)
    {
        decimal outVal = 0m;
        if (decimal.TryParse(temp[1], out outVal)) isOK = true;
    }

    MessageBox.Show(isOK ? "currency format" : "error wrong format");

}

Обратите внимание на несколько вещей:

  • Ожидается, что
  • curCulture будет содержать желаемый формат (вы можете даже учет различных культур/валют/форматов). Из вашего примера кажется, что вы хотите: CultureInfo curCulture = new CultureInfo("en-US", true);.
  • Анализ входной строки может быть как можно более сложным. Например: в опубликованном коде я также уверен, что символ валюты находится в первой позиции.

---- UPDATE (учет десятичных синтаксических разладок с разделителями тысяч)

После подтверждения того, что предлагаемый Decimal.TryParse (и другие эквивалентные подходы) не обеспечивает то, что ожидается, когда задействуются разделители тысяч (разделители групп), я решил написать ниже код, который позаботится об этих проблемах, В любом случае, помните, что я не слишком опытен в этих ситуациях (т.е. Занимаюсь неправильными десятичными входами, составляющими тысячи разделителей) и почему не уверен, есть ли более эффективные способы решения этой проблемы (хотя предлагаемый анализ конечно быстро).

private void btn_Click(object sender, EventArgs e)
{
    //Note: ideally, curCulture shouldn't be defined here (but globally or  
    //passed as argument), but otherwise my code would be somehow incomplete.
    CultureInfo curCulture = new CultureInfo("en-US", true);

    bool isOK = false;
    string[] temp = totalTextBox.Text.Trim().Split(new string[] { curCulture.NumberFormat.CurrencySymbol }, StringSplitOptions.None);
    if (temp.Length == 2 && temp[0].Trim().Length == 0)
    {
        isOK = isDecimalOK(temp[1], curCulture);
    }

    MessageBox.Show(isOK ? "currency format" : "error wrong format");
}

private bool isDecimalOK(string inputString, CultureInfo curCulture)
{
    bool isOK = false;

    string[] temp = inputString.Split(new string[] { curCulture.NumberFormat.CurrencyDecimalSeparator }, StringSplitOptions.None);
    if (temp.Length > 2) return isOK;

    int outVal0 = 0;
    if (!int.TryParse(temp[0], NumberStyles.AllowThousands, curCulture, out outVal0)) return isOK;
    else if (analyseThousands(temp[0], curCulture))
    {
        isOK = (temp.Length == 2 ? int.TryParse(temp[1], NumberStyles.Integer, curCulture, out outVal0) : true);
    }

    return isOK;
}

private bool analyseThousands(string intInput, CultureInfo curCulture)
{

    string[] temp2 = intInput.Split(new string[] { curCulture.NumberFormat.CurrencyGroupSeparator }, StringSplitOptions.None);

    if (temp2.Length >= 2)
    {
        if (temp2[0].Trim().Length == 0) return false;
        else
        {
            for (int i2 = 1; i2 < temp2.Length; i2++)
            {
                if (!curCulture.NumberFormat.CurrencyGroupSizes.Contains(temp2[i2].Length)) return false;
            }
        }
    }

    return true;
}

Ответ 2

Вы можете попытаться использовать регулярное выражение:

var moneyR = new Regex(@"^\$(((\d{1,3},)+\d{3})|\d+)(\.\d{2}){0,1}$");
if (moneyR.IsMatch(yourValue))
{
    MessageBox.Show("Ok");
}
else
{
    MessageBox.Show("Wrong");
}

Ответ 3

Чтобы проверить формат, вы можете попытаться выполнить его синтаксический анализ таким образом:

        string s = "$123.78";
        float f;
        if (float.TryParse(s, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out f))
        {
            // OK
        }
        else
        {
            // WRONG
        }

Ответ 4

Попробуйте это, это должно быть работа

string money = "$12,345.00";
float f;
if (float.TryParse(money, NumberStyles.Currency, CultureInfo.GetCultureInfo("en-US"), out f))
{
   // valid
}
else
{
    // invalid 
}

Отладочная информация: введите описание изображения здесь

Вывод:

введите описание изображения здесь