0

我正在使用 ValueConverter 将double类型显示为货币。我想确保输入是有效的,所以我尝试使用我制作的这种验证方法。我唯一的问题似乎是我无法选择整个值(即 500.00 美元)并输入任何内容。如果未选择“$”,一切似乎都很好。我怎样才能解决这个问题?

XAML:

<TextBox Text="{Binding Converter={StaticResource MoneyConverter}, Path=fr}"
  PreviewTextInput="ValidateMoney" DataObject.Pasting="TextBox_Pasting"/>

后面的代码:

private void ValidateMoney(object sender, TextCompositionEventArgs e) {
  Regex rgx = new Regex(@"^(\$)[0-9]*[.]{0,1}[0-9]*$|^[.][0-9]+$|^[0-9]*[.]{0,1}[0-9]*$");
  e.Handled = !rgx.IsMatch((sender as TextBox).Text.Insert((sender as TextBox).SelectionStart, e.Text));
}
public class MoneyConverter : IValueConverter {
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
    if (value != null) {
      double d;
      string temp = value.ToString();
      if (double.TryParse(temp, out d)) {
        return String.Format("{0:C}", d);
      } else {
        return value;
      }
    } else {
      return value;
    }
  }
  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
    if (value != null) {
      double d;
      string temp = value.ToString();
      if (double.TryParse(temp, out d)) {
        return String.Format("{0:C}", d);
      } else {
        return value;
      }
    } else {
      return value;
    }
  }
}
4

1 回答 1

3

您包含美元符号的方法是正确的,尽管括号是不必要的。写这个就足够了:^\$.

您可以大大简化您的正则表达式:

  • 您不需要交替使用三个单独的案例。那里有一些不必要的重复。
  • {0,1}可以替换为?
  • 您可能希望确保至少有一位数字。

试试这个:

@"^\$?(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)$"

或者使用捕获组来减少混乱:

@"^\$?([0-9]+(\.[0-9]+)?|\.[0-9]+)$"

其他几点:

  • 您应该知道TryParse受当前文化的影响。1.990根据您的文化,意味着不同的东西。
  • ToString也取决于文化。该"{0:C}"格式不保证美元符号。
  • 您的正则表达式允许$.990. 这可能是你想要的,但对我来说它看起来有点奇怪。
  • 您可能应该使用decimal而不是double存储货币金额。double类型不能1.99准确存储,但可以decimal
  • 我换成[.]了等价物\.,但这只是口味问题。两者都做同样的事情。
于 2012-11-12T20:37:13.017 回答