.NET Framework 中的区域设置覆盖
Regional Settings Override in .NET Framework
我目前遇到了数字格式问题,我真的不知道如何解决。
我使用了 Support
程序集中的函数:
'StringToFormat looks like "123.456789"
'FormatInfo looks like "0.000" (must display three decimals)
Support.Format(StringToFormat, FormatInfo)
它工作正常,但当我的区域设置设置不正确时,它不起作用...StringToFormat
是一个来自另一个应用程序的变量(超过 TCP/IP),我无法改变它。因此,当小数分隔符设置为逗号而不是点时,Format 函数会做一些奇怪的事情并且无法正确显示我的值。
为了解决这个问题,我写了一个小函数,它实际上创建了一个新的文化并确保小数点分隔符是点:
Sub UpdateRegionalSettings()
'I call this everytime I start my application
My.Application.ChangeCulture("x-en-US-custom")
End Sub
Sub CreateMyCulture()
'This function is called only if the culture doesn't exist yet
Dim C As New CultureAndRegionInfoBuilder("x-en-US-custom", CultureAndRegionModifiers.None)
C.LoadDataFromCultureInfo(New CultureInfo("en-US"))
C.LoadDataFromRegionInfo(New RegionInfo("US"))
C.NumberFormat.NumberDecimalSeparator = "."
C.NumberFormat.CurrencyDecimalSeparator = "."
C.Register()
End Sub
但是,这似乎不起作用,因为当我进入区域设置并将分隔符更改为逗号时,Format 函数又变得奇怪了。就像这些参数覆盖了我在程序中可以说的任何内容...
我的问题是:如何强制 Support.Format
(和其他)功能使用点作为小数点分隔符,而无需手动将其设置为控制面板的区域和语言?
这是一种仅在运行时更改应用文化的方法。在表单加载中加载所有区域性,因此您可以修改它们并在双精度和日期时间的文本框控件中查看结果。
Imports System.Globalization
''' <summary>
''' Requires
''' 1 ComboBox: cboCultures
''' 2 TextBoxes: TextBox1, TextBox2
''' 1 DateTimePicker: DateTimePicker1
''' </summary>
Public Class Form1
' Used to set cboCultures selected item and for restoring the current culture
Private OriginalCultureName As String = ""
Private OriginalCultureIndex As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
OriginalCultureName = Application.CurrentCulture.Name
DateTimePicker1.Format = DateTimePickerFormat.Custom
cboCultures.DisplayMember = "DisplayName"
cboCultures.ValueMember = "Code"
cboCultures.DropDownStyle = ComboBoxStyle.DropDownList
Dim CultureList =
(
From cultureitem In CultureInfo.GetCultures(CultureTypes.SpecificCultures)
Order By cultureitem.EnglishName
Select New With
{
.DisplayName = cultureitem.EnglishName,
.Code = cultureitem.Name
}
).ToList
cboCultures.DataSource = CultureList
' get current culture so we can select it in cboCultures
Dim item =
(
From T In CultureList _
.Select(
Function(cultureitem, indexer)
Return New With {.Index = indexer, .Name = cultureitem.Code}
End Function)
Where T.Name = OriginalCultureName
).First
OriginalCultureIndex = item.Index
cboCultures.SelectedIndex = OriginalCultureIndex
End Sub
Private Sub cmdChange_Click(sender As Object, e As EventArgs) Handles cmdChange.Click
Application.CurrentCulture = New CultureInfo(cboCultures.SelectedValue.ToString)
Demo()
End Sub
''' <summary>
''' Show results for date and double
''' </summary>
Private Sub Demo()
DateTimePicker1.CustomFormat = DateTimeFormatInfo.CurrentInfo.FullDateTimePattern
TextBox1.Text = DateTimePicker1.Value.ToString
Dim value As Double = 123.456789
TextBox2.Text = value.ToString
End Sub
Private Sub cmdRestore_Click(sender As Object, e As EventArgs) Handles cmdRestore.Click
Application.CurrentCulture = New CultureInfo(OriginalCultureName)
cboCultures.SelectedIndex = OriginalCultureIndex
cmdChange.PerformClick()
Demo()
End Sub
End Class
更新:我使用了下面的字符串格式,它对我有用
Private Sub Demo()
DateTimePicker1.CustomFormat = DateTimeFormatInfo.CurrentInfo.FullDateTimePattern
TextBox1.Text = DateTimePicker1.Value.ToString
Dim value As Double = 123.456789
TextBox2.Text = value.ToString("c2")
TextBox3.Text = String.Format("{0:c2}", value)
End Sub
不确定 Support.Format 函数,因为我不使用它,但我在使用小数分隔符时遇到了同样的问题,并通过从用户的区域设置中克隆当前区域性,然后设置适当的属性,然后将更改应用到应用程序线程。这允许我的应用程序正常运行而无需更改(或担心)用户的区域设置。
Dim cinfo As CultureInfo = Thread.CurrentThread.CurrentCulture.Clone()
cinfo.NumberFormat.NumberDecimalSeparator = "."
cinfo.NumberFormat.CurrencyDecimalSeparator = "."
cinfo.NumberFormat.CurrencyDecimalDigits = 2
Thread.CurrentThread.CurrentCulture = cinfo
我目前遇到了数字格式问题,我真的不知道如何解决。
我使用了 Support
程序集中的函数:
'StringToFormat looks like "123.456789"
'FormatInfo looks like "0.000" (must display three decimals)
Support.Format(StringToFormat, FormatInfo)
它工作正常,但当我的区域设置设置不正确时,它不起作用...StringToFormat
是一个来自另一个应用程序的变量(超过 TCP/IP),我无法改变它。因此,当小数分隔符设置为逗号而不是点时,Format 函数会做一些奇怪的事情并且无法正确显示我的值。
为了解决这个问题,我写了一个小函数,它实际上创建了一个新的文化并确保小数点分隔符是点:
Sub UpdateRegionalSettings()
'I call this everytime I start my application
My.Application.ChangeCulture("x-en-US-custom")
End Sub
Sub CreateMyCulture()
'This function is called only if the culture doesn't exist yet
Dim C As New CultureAndRegionInfoBuilder("x-en-US-custom", CultureAndRegionModifiers.None)
C.LoadDataFromCultureInfo(New CultureInfo("en-US"))
C.LoadDataFromRegionInfo(New RegionInfo("US"))
C.NumberFormat.NumberDecimalSeparator = "."
C.NumberFormat.CurrencyDecimalSeparator = "."
C.Register()
End Sub
但是,这似乎不起作用,因为当我进入区域设置并将分隔符更改为逗号时,Format 函数又变得奇怪了。就像这些参数覆盖了我在程序中可以说的任何内容...
我的问题是:如何强制 Support.Format
(和其他)功能使用点作为小数点分隔符,而无需手动将其设置为控制面板的区域和语言?
这是一种仅在运行时更改应用文化的方法。在表单加载中加载所有区域性,因此您可以修改它们并在双精度和日期时间的文本框控件中查看结果。
Imports System.Globalization
''' <summary>
''' Requires
''' 1 ComboBox: cboCultures
''' 2 TextBoxes: TextBox1, TextBox2
''' 1 DateTimePicker: DateTimePicker1
''' </summary>
Public Class Form1
' Used to set cboCultures selected item and for restoring the current culture
Private OriginalCultureName As String = ""
Private OriginalCultureIndex As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
OriginalCultureName = Application.CurrentCulture.Name
DateTimePicker1.Format = DateTimePickerFormat.Custom
cboCultures.DisplayMember = "DisplayName"
cboCultures.ValueMember = "Code"
cboCultures.DropDownStyle = ComboBoxStyle.DropDownList
Dim CultureList =
(
From cultureitem In CultureInfo.GetCultures(CultureTypes.SpecificCultures)
Order By cultureitem.EnglishName
Select New With
{
.DisplayName = cultureitem.EnglishName,
.Code = cultureitem.Name
}
).ToList
cboCultures.DataSource = CultureList
' get current culture so we can select it in cboCultures
Dim item =
(
From T In CultureList _
.Select(
Function(cultureitem, indexer)
Return New With {.Index = indexer, .Name = cultureitem.Code}
End Function)
Where T.Name = OriginalCultureName
).First
OriginalCultureIndex = item.Index
cboCultures.SelectedIndex = OriginalCultureIndex
End Sub
Private Sub cmdChange_Click(sender As Object, e As EventArgs) Handles cmdChange.Click
Application.CurrentCulture = New CultureInfo(cboCultures.SelectedValue.ToString)
Demo()
End Sub
''' <summary>
''' Show results for date and double
''' </summary>
Private Sub Demo()
DateTimePicker1.CustomFormat = DateTimeFormatInfo.CurrentInfo.FullDateTimePattern
TextBox1.Text = DateTimePicker1.Value.ToString
Dim value As Double = 123.456789
TextBox2.Text = value.ToString
End Sub
Private Sub cmdRestore_Click(sender As Object, e As EventArgs) Handles cmdRestore.Click
Application.CurrentCulture = New CultureInfo(OriginalCultureName)
cboCultures.SelectedIndex = OriginalCultureIndex
cmdChange.PerformClick()
Demo()
End Sub
End Class
更新:我使用了下面的字符串格式,它对我有用
Private Sub Demo()
DateTimePicker1.CustomFormat = DateTimeFormatInfo.CurrentInfo.FullDateTimePattern
TextBox1.Text = DateTimePicker1.Value.ToString
Dim value As Double = 123.456789
TextBox2.Text = value.ToString("c2")
TextBox3.Text = String.Format("{0:c2}", value)
End Sub
不确定 Support.Format 函数,因为我不使用它,但我在使用小数分隔符时遇到了同样的问题,并通过从用户的区域设置中克隆当前区域性,然后设置适当的属性,然后将更改应用到应用程序线程。这允许我的应用程序正常运行而无需更改(或担心)用户的区域设置。
Dim cinfo As CultureInfo = Thread.CurrentThread.CurrentCulture.Clone()
cinfo.NumberFormat.NumberDecimalSeparator = "."
cinfo.NumberFormat.CurrencyDecimalSeparator = "."
cinfo.NumberFormat.CurrencyDecimalDigits = 2
Thread.CurrentThread.CurrentCulture = cinfo