【新特性速递】当法语遇上FineUI(Bonjour)!
上个版本,我们为数字输入框增加了 DotSeparator 和 CommaSeparator,对于特殊语种会非常有用。
https://www.cnblogs.com/sanshi/p/12836430.html
比如在法语或者西班牙语的环境下,小数分隔符和千分位分隔符和我们正常的认知是不同的。
下面这个数字(以字符串表示):
"1,682.80"
在法语环境下,应该写作:
"1.682,80"
那么这个特性具体该怎么使用呢?
数据库与页面显示
不管是什么语言,在数据库中定义为 decimal 或者 int 时,内部保存的都是标准的数字类型。
在法语环境下,页面上显示的效果:
页面上显示时,千分位分隔符是点号,而小数分隔符是逗号,和我们标准的数字格式刚好相反。
配置语言
在 Global.asax 中,配置法语环境:
1 2 3 4 5 | protected void Application_BeginRequest( object sender, EventArgs e) { Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture( "es" ); Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo( "es" ); } |
配置数字输入框
配置数字输入框的 DotSeparator和CommaSeparator,可以在三个不同的层级配置。
Web.config中:
1 | < FineUIPro FormDotSeparator="," FormCommaSeparator="." /> |
在页面上,可以设置 PageManager 的相应属性,参考官网示例源代码,可以在 PageBase.cs 中设置:
1 2 3 4 5 6 7 8 9 10 | protected override void OnInit(EventArgs e) { var pm = PageManager.Instance; if (pm != null ) { pm.FormDotSeparator = "," ; pm.FormCommaSeparator = "." ; } } |
当然,也可以直接设置 NumberBox 控件的相应属性:
1 2 | < f:NumberBox Label="小数" ID="NumberBox1" runat="server" Text="-12345.6789" EnableCommas="true" Required="true" ShowRedStar="true" DecimalPrecision="2" DotSeparator="," CommaSeparator="." /> |
数字输入框 - 读取
页面标签:
1 2 3 4 | < f:NumberBox Label="Decimal1" ID="txtDecimal1" runat="server" EnableCommas="true" /> < f:NumberBox Label="Decimal2" ID="txtDecimal2" runat="server" EnableCommas="true" /> < f:NumberBox Label="Decimal3" ID="txtDecimal3" runat="server" EnableCommas="true" /> < f:NumberBox Label="Decimal4" ID="txtDecimal4" runat="server" EnableCommas="true" NoDecimal="true"/> |
后台数据库读取省略,假设我们有一个方法可以将数据读取到一个DataTable中,类似如下:
1 | DataTable table = GetTableFromDB( "select * from Ceshi where id='3d1980b7-b195-4212-87c4-903c5df119db'" ); |
下面需要对 NumberBox 进行赋值,这里还要再次提到一个原则:
不管页面上显示的格式如何,对控件赋值或者获取都是标准的数字格式(也即是去除千分位,小数点用点号表示的字符串)!
所以,我们需要将标准的数字类型转换为字符串(标准格式,忽略方言):
NumberFormatInfo.InvariantInfo - 获取不依赖于区域性的(固定)只读的 System.Globalization.NumberFormatInfo 对象。
1 2 3 4 | txtDecimal1.Text = (( decimal )table.Rows[0][ "Decimal1" ]).ToString(NumberFormatInfo.InvariantInfo); txtDecimal2.Text = (( decimal )table.Rows[0][ "Decimal2" ]).ToString(NumberFormatInfo.InvariantInfo); txtDecimal3.Text = (( decimal )table.Rows[0][ "Decimal3" ]).ToString(NumberFormatInfo.InvariantInfo); txtDecimal4.Text = (( int )table.Rows[0][ "Decimal4" ]).ToString(NumberFormatInfo.InvariantInfo); |
文本标签 - 读取
页面标签:
1 2 3 4 | < f:Label Label="Decimal1" ID="lblDecimal1" runat="server" /> < f:Label Label="Decimal2" ID="lblDecimal2" runat="server" /> < f:Label Label="Decimal3" ID="lblDecimal3" runat="server" /> < f:Label Label="Decimal4" ID="lblDecimal4" runat="server" /> |
后台直接使用 String.Format 进行格式化(添加千分位分隔符):
1 2 3 4 | lblDecimal1.Text = string .Format( "{0:N2}" , table.Rows[0][ "Decimal1" ]); lblDecimal2.Text = string .Format( "{0:N2}" , table.Rows[0][ "Decimal2" ]); lblDecimal3.Text = string .Format( "{0:N2}" , table.Rows[0][ "Decimal3" ]); lblDecimal4.Text = string .Format( "{0:N0}" , table.Rows[0][ "Decimal4" ]); |
显示效果:
数字输入框 - 保存
保存数据库前,我们需要将数字输入框的文本值转换为数字类型:
1 2 3 4 | var decimal1 = Convert.ToDecimal(txtDecimal1.Text, NumberFormatInfo.InvariantInfo); var decimal2 = Convert.ToDecimal(txtDecimal2.Text, NumberFormatInfo.InvariantInfo); var decimal3 = Convert.ToDecimal(txtDecimal3.Text, NumberFormatInfo.InvariantInfo); var decimal4 = Convert.ToInt32(txtDecimal4.Text, NumberFormatInfo.InvariantInfo); |
和之前的代码类似,我们同样需要指定 NumberFormatInfo.InvariantInfo,以便告诉转换器以标准的格式解析数字字符串。
表格 - 读取
1. BoundField
由于BoundField是在后台绑定的数据,所以可以直接指定 DataFormatString 来格式化数字,如下所示:
1 2 3 4 | < f:BoundField Width="150px" DataField="Decimal1" ColumnID="Decimal1" HeaderText="Decimal1" DataFormatString="{0:N2}" /> < f:BoundField Width="150px" DataField="Decimal2" HeaderText="Decimal2" DataFormatString="{0:N2}" ColumnID="Decimal2" /> < f:BoundField Width="150px" DataField="Decimal3" HeaderText="Decimal3" DataFormatString="{0:N2}" ColumnID="Decimal3" /> < f:BoundField Width="150px" DataField="int" HeaderText="Decimal4" DataFormatString="{0:N0}" ColumnID="Decimal4" /> |
显示效果:
2. RenderField
RenderField可以指定 FieldType,这样可以在客户端格式化数字输出:
1 2 3 4 | < f:RenderField Width="150px" DataField="Decimal1" FieldType="Double" HeaderText="Decimal1" RendererFunction="renderDecimal" /> < f:RenderField Width="150px" DataField="Decimal2" FieldType="Double" HeaderText="Decimal2" RendererFunction="renderDecimal" /> < f:RenderField Width="150px" DataField="Decimal3" FieldType="Double" HeaderText="Decimal3" RendererFunction="renderDecimal" /> < f:RenderField Width="150px" DataField="int" FieldType="Int" HeaderText="Decimal4" RendererFunction="renderDecimal" /> |
显示效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <script> function renderDecimal2(value) { value += '' ; value = value.replace( '.' , ',' ); return F.addCommas(value, ',' , '.' ); } function renderDecimal(value) { return F.addDotSeparator(value, ',' , '.' ); } </script> |
注:客户端函数 F.addDotSeparator 会在 FineUIPro/Mvc/Core v6.4.0 中提供!
单元格编辑
单元格编辑必须使用RenderField,所以只能在客户端进行格式化,页面代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | < f:RenderField Width="150px" ColumnID="decimal1" RendererFunction="renderDecimal" DataField="Decimal1" FieldType="Double" HeaderText="Decimal1"> < Editor > < f:NumberBox EnableCommas="true" runat="server"> </ f:NumberBox > </ Editor > </ f:RenderField > < f:RenderField Width="150px" ColumnID="decimal2" RendererFunction="renderDecimal" DataField="Decimal2" FieldType="Double" HeaderText="Decimal2"> < Editor > < f:NumberBox EnableCommas="true" runat="server"> </ f:NumberBox > </ Editor > </ f:RenderField > < f:RenderField Width="150px" ColumnID="decimal3" RendererFunction="renderDecimal" DataField="Decimal3" FieldType="Double" HeaderText="Decimal3"> < Editor > < f:NumberBox EnableCommas="true" runat="server"> </ f:NumberBox > </ Editor > </ f:RenderField > < f:RenderField Width="150px" ColumnID="decimal4" RendererFunction="renderDecimal" DataField="int" FieldType="Int" HeaderText="Decimal4"> < Editor > < f:NumberBox EnableCommas="true" NoDecimal="true" runat="server"> </ f:NumberBox > </ Editor > </ f:RenderField > |
显示效果:
单元格编辑时效果:
此时,在页面上执行如下JS脚本:
1 | F.toJSON(F.ui.Grid1.getMergedData()) |
得到的数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | [{ "index" : 0, "values" : { "decimal1" : 123.22, "decimal2" : 12345.6, "decimal3" : 12.34, "decimal4" : 123456 }, "status" : "modified" }, { "index" : 1, "values" : { "decimal1" : 123, "decimal2" : 123, "decimal3" : 2312, "decimal4" : 456 }, "status" : "unchanged" }, { "index" : 2, "values" : { "decimal1" : 1234.56, "decimal2" : 23456789, "decimal3" : 0, "decimal4" : 800600 }, "status" : "unchanged" }] |
三石出品,必属精品!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2009-06-11 jStyle v0.1 beta2