2014-03-26 3 views
2

У меня есть текстовое поле в winforms C#.Формат денег TextBox с 1 запятой

private void textBox1_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     if (!char.IsNumber(e.KeyChar) & (Keys)e.KeyChar != Keys.Back 
       & e.KeyChar != ',') 
     { 
      e.Handled = true; 
     } 

     base.OnKeyPress(e); 
    } 

выше код работает очень хорошо, однако я могу добавить 2 запятую как «100,, 00» .Как я могу только позволить пользователю добавлять «100,00» или «100000000» с 1 запятая как формат денег?

Любая помощь будет оценена по достоинству.

Спасибо.

+1

Имейте в виду, что жестко прописывать запятой в качестве десятичного разделителя действительно не является хорошей идеей. Вы должны соблюдать региональные настройки конечного пользователя. Или, по крайней мере, работайте с культурой ui, с которой вы определяете свое приложение. – Crono

ответ

1

Как указано Хроно в другой ответ, MaskedTextBox является лучшим решением.Но если вы действительно хотите добавить ограничения и форматирование в текстовое поле, вы можете просто проанализировать текст в decimal, а затем полностью заменить ключ запятой и разрешить только одно десятичное число.

Это немного взломан вместе, но должны добиться того, что вы ищете:

Сначала нужно создать обработчик событий, чтобы не допустить запись запятой и только позволяют один десятичную точку

private void textBox1_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     //Just don't let them type commas - We will format after the TextBox is left 
     if (!char.IsControl(e.KeyChar) 
      && !char.IsDigit(e.KeyChar) 
      && e.KeyChar == ',') 
     { 
      e.Handled = true; 
     } 

     // only allow one decimal point 
     if (e.KeyChar == '.' 
      && (sender as TextBox).Text.IndexOf('.') > -1) 
     { 
      e.Handled = true; 
     } 
    } 

Затем создайте немного вспомогательный метод для анализа значения вашего TextBox к decimal

private decimal GetValueFromTextBox(string input) 
    { 
     input = System.Text.RegularExpressions.Regex.Replace(input, @"[,$%]", String.Empty); 
     //Could use Try parse here for better handling 
     decimal output = Convert.ToDecimal(input); 
     return output; 
    } 

Тогда просто вызовите функцию от вашего TextBox_Leave событие:

private void textBox1_Leave(object sender, EventArgs e) 
    { 
     var value = GetValueFromTextBox(textBox1.Text); 

     textBox1.Text = value.ToString("c"); 
    } 

Это формат значение в формате валюта с надлежащим размещением запятой исполнения только один десятичной точки а. Опять НЕ ЛУЧШЕЕ РЕШЕНИЕ (используйте MaskedTextBox), но он будет работать для обычного управления TextBox.

5

Не прямой ответ на ваш вопрос, но наиболее определенно совет, который вы должны рассмотреть: используйте для этого MaskedTextBox, а не TextBox.

A MaskedTextBox имеет свойство Mask, которое действует как шаблон для текстовых значений. В вашем случае соответствующая маска, вероятно, будет #,###.##. Обратите внимание, что в зависимости от культуры ваша сборка находится в десятичном разделителе, может быть чем-то другим, кроме запятой. Тем не менее, вы сможете преобразовать это в числовое значение, которое, безусловно, то, что вы хотите в любом случае.

UPDATE:

В качестве дополнительных рекомендаций, некоторые 3-производители партии, как действительно предлагают элементы управления с более продвинутыми входами маски, которые могут использовать традиционные маски, а также регулярные выражения на основе валидаторов. Если вы можете позволить себе деньги, это может занять какое-то время.

+0

у него есть ограничение для numbers.i можете ввести maxmimujm 6 чисел в вашем примере. Как я могу сделать это безграничным? – user3409638

+0

@ user3409638 Насколько я знаю, нет никакого способа сделать это безграничным. Я полагаю, вы могли бы динамически создавать маску, но это может быть не то, что вам хотелось бы. Особенно, если вам нужны дополнительные символы, такие как валюта. – Crono

0

Вы можете ограничить допустимый ввод в текстовое поле с помощью нно в MaskedTextbox,

Если вы хотите проверить это логически/вручную, добавить что-то вроде: !textBox1.Text.Contains(',').

Это вернет true, только если в текстовом поле еще нет запятой.

Edit: На самом деле, я не уверен, что если новодобавленный запятая будет включен до или после нажатия клавиши-события - если это включен, то вы, возможно, придется использовать вместо рассчитывать:

if(... && (textBox1.Text.Count(c => c == ',') <= 1)) 
{ 
    .... 
} 

PS: я бы реорганизовать этот код и перенести испытания в отдельные методы для чистоты, поэтому основной тест будет выглядеть примерно так:

if(IsValidChar(e.KeyChar) && IsOnlyOneCommaProvided()){ 
    ... 
} 
1

Вы можете использовать NumericUpDown, чтобы избежать ручной проверки номеров.

+0

Я лично ненавижу этот элемент управления, не позволяя легко удалять кнопки, но это другая и интересная идея. +1 – Crono

0

Вы можете использовать регулярное выражение, как [\ d] *, [\ d] *, которое обеспечит его соответствие только одному из чисел, имеющих максимум одну запятую.

Обновление: кое-что вдоль линий этого:

private void textBox1_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    var newString = textBox1.Text += e.KeyChar; 
    if(!Regex.IsMatch(newString, "[\d]*,[\d]*")) 
     e.Handled = true; 

    base.OnKeyPress(e); 
} 
+0

где я должен добавить ваш код в текстовое поле? – user3409638

+0

так? он вел себя по-своему? – Dbl

+0

"[\ d] *, [\ d] *" имеет неправильные значения, это была красная строка под "[\ d] *, [\ d] *". Я имею в виду, что он имеет синтаксическую ошибку. – user3409638

0

Я рекомендую проверить сторонние элементы управления. Они экономят много времени (это деньги) и головные боли. Элемент управления DevExpress TextEdit делает это ... это простой вариант, который не требует времени для установки. Я предполагаю, что все остальные (Telerik, Infragistics и т. Д.) Тоже делают это.

-1

Как насчет решения на основе javascript?

Он выигрывает от независимости от платформы и заботится о позиции курсора в текстовом поле, а также не требует обработки на стороне сервера, что всегда приятно.

Один недостаток - если JS отключен, другой должен «очистить» значения запятых на стороне сервера, когда они будут отправлены. Все и все, что я подумал бы, было бы гораздо более элегантным решением.

просто добавить в свой текстовое поле type='tel' атрибут как:

<input type='tel' /> 



<script type="text/javascript"> 
    $(function() { 
     $("[type='tel']").keydown(function (event) { 
      var position = this.selectionStart; 
      var $this = $(this); 
      var val = $this.val(); 
      if (position == this.selectionEnd && 
       ((event.keyCode == 8 && val.charAt(position - 1) == "," && val.substr(0, position - 1).indexOf(".") == -1) 
       || (event.keyCode == 46 && val.charAt(position) == "," && val.substr(0, position).indexOf(".") == -1))) { 
       event.preventDefault(); 
       if (event.keyCode == 8) { 
        $this.val(val.substr(0, position - 2) + val.substr(position)); 
        position = position - 2; 
       } else { 
        $this.val(val.substr(0, position) + val.substr(position + 2)); 
       } 
       $this.trigger('keyup', { position: position }); 
      } else { 
       this.dispatchEvent(event); 
      } 
     }); 

       $("[type='tel']").keyup(function(event, args) { 
         if (event.which >= 37 && event.which <= 40) { 
           event.preventDefault(); 
         } 

         var position = args ? args.position : this.selectionStart; 
         var $this = $(this); 
         var val = $this.val(); 
         var parts =val.split("."); 
        var valOverDecimalPart = parts[0]; 
         var commaCountBefore = valOverDecimalPart.match(/,/g) ? valOverDecimalPart.match(/,/g).length : 0; 
         var num = valOverDecimalPart.replace(/[^0-9]/g, ''); 
         var result = parts.length == 1 ? num.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,") : num.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,") +"."+ parts[1].replace(/[^0-9.]/g,""); 
        $this.val(result); 
        var commaCountAfter = $this.val().match(/,/g) ? $this.val().match(/,/g).length : 0; 
         position = position + (commaCountAfter - commaCountBefore); 
         this.setSelectionRange(position, position); 
       }); 
      }); 
    </script> 
Смежные вопросы