65.9K
CodeProject 正在变化。 阅读更多。
Home

本地化的货币文本框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.41/5 (24投票s)

2005年6月8日

4分钟阅读

viewsIcon

215478

downloadIcon

2333

一个本地化的货币文本框控件。

Sample Image

引言

我试图找到一个合适的控件来显示和编辑可以绑定到小数值的正确格式化的货币值,但都徒劳无功,于是我开始创建我的第一个自定义 Web 控件。

注意:下载中还包含一个 PercentBoxNumberBox 控件,它们使用相同的原理。

控件要求

第一步是定义控件的基本要求。

  • 允许数据绑定到小数类型。
  • 以货币文本形式显示值,并根据当前区域性进行格式化。
  • 用不同的颜色显示负值。
  • 只允许有效的数据输入。
  • 在客户端执行与验证输入和格式化货币值相关的操作。

开始

虽然控件渲染为文本框 <INPUT type="text" ...>,但继承自 System.Web.UI.WebControls.TextBox 会需要隐藏很多属性,因此该控件继承自 System.Web.UI.WebControls.WebControl 并实现了 IPostBackDataHandler

属性

向基类添加了十一个公共属性来控制其外观

  • Alignment:设置控件中文本的对齐方式(默认为 Right)。
  • Amount:要绑定到控件的小数值。该值存储在 ViewState 中,并且 IPostBackDataHandler 的实现确保在适当时候引发 AmountChanged 事件。
    [
    DefaultValue(typeof(decimal),"0"),
    Category("Appearance"),
    Bindable(true),
    Description("The amount displayed in the control")
    ]
    public decimal Amount
    {
      get
      {
        // Check if a value has been assigned
        object amount = ViewState["amount"];
        if (amount == null)
          // Return the default
          return 0M;
        else
          // Return the value
          return (decimal)amount;
      }
      set
      {
        ViewState["amount"] = value;
        // Set the text colour
        if (value < 0)
          base.ForeColor = NegativeColor;
        else
          base.ForeColor = PositiveColor;
      }
    }
  • MinAmount:设置用户可以输入的最小值。
  • MaxAmount:设置用户可以输入的最大值。
  • NegativeColor:设置当 Amount 为负值 (<0) 时显示的颜色。
    [
    DefaultValue(typeof(Color),"Red"),
    Category("Appearance"),
    Bindable(true),
    Description("The colour of negative currency values")
    ]
    public Color NegativeColor
    {
      get
      {
        return _NegativeColor;
      }
      set
      {
        _NegativeColor = value;
        // Set the controls ForeColor if appropriate
        if (Amount < 0)
          base.ForeColor = value;
      }
    }
  • OnBlurOnFocusOnKeyPress:控件为这些 HTML 事件输出 JavaScript 代码,这些属性允许分配额外的脚本。
  • PositiveColor:设置当 Amount 为正值时显示的颜色。
  • Precision:格式化金额时显示的位数。
  • Text:一个 只读 属性,返回根据当前区域性格式化后的 Amount

此外,基类的 ForeColor 属性被隐藏,以实现其为 只读(因为它的颜色是通过 PositiveColorNegativeColor 属性设置的)。

渲染控件

默认情况下,WebControl 渲染为 <SPAN>。要渲染为文本框 <INPUT>,我们必须首先重写 TagKey

protected override HtmlTextWriterTag TagKey
{
  get
  {
    return HtmlTextWriterTag.Input;
  }
}

然后通过重写 AddAttributesToRender 来添加属性。

protected override void AddAttributesToRender(HtmlTextWriter writer)
{
  base.AddAttributesToRender(writer);
  // Add attributes necessary to display an text control
  writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
  writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
  writer.AddAttribute(HtmlTextWriterAttribute.Value, Text);
  writer.AddStyleAttribute("text-align", Alignment.ToString());
  // Add user defined attributes to control colour formatting
  writer.AddAttribute("negativeColor", NegativeColor.Name);
  if (PositiveColor != Color.Empty)
  {
    writer.AddAttribute("positiveColor", PositiveColor.Name);
  }
  // Add client side event handlers
  writer.AddAttribute("onkeypress", "EnsureNumeric()");
  writer.AddAttribute("onfocus", "FormatAsDecimal(this)");
  writer.AddAttribute("onblur", "FormatAsCurrency(this)");
}

将两个用户定义的属性添加到渲染的控件中,positiveColornegativeColor。这两个属性由客户端脚本读取,以根据其值设置文本的颜色。此外,还为下面讨论的脚本函数分配了三个客户端事件。

客户端脚本

重写基类的 OnPreRender 方法以获取当前区域性的 NumberFormat。然后检查脚本是否已注册,如果没有,则调用代码使用 NumberFormat 来构造它们,最后注册它们。

protected override void OnPreRender(EventArgs e)
{
  // Get the number format of the current culture
  NumberFormatInfo format = Thread.CurrentThread.CurrentCulture.NumberFormat;
  // Register the EnsureNumeric script
  if (!Page.IsClientScriptBlockRegistered("EnsureNumeric"))
  {
    Page.RegisterClientScriptBlock("EnsureNumeric",EnsureNumericScript(format));
  }
  ...........

注册了五个脚本函数。

  • EnsureNumeric() 分配给 OnKeyPress 事件,限制键盘输入为有效值。
  • FormatCurrencyAsDecimal() 分配给 OnFocus 事件。它调用 CurrencyToDecimal() 函数,并根据返回的值格式化其文本。
  • FormatDecimalAsCurrency() 分配给 OnBlur 事件。它调用 DecimalToCurrency() 函数,并根据返回的值格式化其文本。
  • CurrencyToDecimal() 将货币字符串解析为十进制值。
  • DecimalToCurrency() 将十进制值格式化为货币字符串。

用于生成这些脚本的代码太长,无法在此处包含,但下载中包含一个 htm 文件,解释了我使用的方法。

使用控件

  • 下载并构建 Web 控件库项目。
  • 创建一个新的 ASP.NET Web 应用程序项目,并将控件添加到工具箱。
  • 将控件拖到窗体上并设置一些属性。
  • 在 ASP.NET Web 应用程序项目的 Web.Config 文件中,修改 globalization 部分以设置特定的区域性(例如,culture="fr-FR"(法语-法国)或 culture="id-ID"(印尼语-印度尼西亚)等)。请注意,必须使用特定区域性,而不是中性区域性。
      <globalization 
        requestEncoding="utf-8" 
        responseEncoding="utf-8" 
        culture="fr-FR"
      />
  • 运行项目。
  • Amount 属性将根据您在 Web.Config 文件中指定的区域性显示。将焦点移到控件上,文本将被解析为十进制值。
  • 输入一个数字值然后移开。文本将被格式化回货币字符串,颜色将根据 PositiveColorNegativeColor 设置。

请注意,在输入数据时,只能输入数字(0-9)、负号和(如果适用)小数点。某些语言(如印尼语)没有小数位,在这种情况下无法输入小数点。另请注意,许多(欧洲)语言的小数分隔符是逗号,而不是小数点。

历史

  • v1.0 - 2005年6月8日 - 创建。
  • v1.1 - 2005年8月4日
    • 添加了 MinAmountMaxAmountOnBlurOnFocusOnKeyPressPrecision 的附加属性。
    • 修改了脚本。
    • NumberBoxPercentBox 添加到项目中。
  • v1.2 - 2005年9月20日
    • 修改了脚本以验证最小值和最大值。
© . All rights reserved.