2016-04-20 11 views
0

В настоящее время я придерживаюсь проблемы форматирования номера, и я действительно не знаю, как его решить.Переопределение региональных настроек в .NET Framework

Я использую функцию из Support сборки:

'StringToFormat looks like "123.456789" 
'FormatInfo looks like "0.000" (must display three decimals) 
Support.Format(StringToFormat, FormatInfo) 

Он отлично работает, когда что Зависит мои региональные настройки не установлены должным образом, он не работает ... StringToFormat является переменным, которые приходят от другого приложение (через TCP/IP), и я не могу его изменить. Поэтому, когда Десятичный разделитель настроен на coma вместо точки, функция 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 (и другие) использовать точку в качестве разделителя десятичной дроби, без необходимости вручную ее устанавливать региона и языка панели управления?

+0

Я был в вашей ситуации несколько месяцев назад, и самым быстрым решением было проверить в «Просмотр номера» и сохранить в базе данных в моем формате. – CristiC777

+0

Используйте Decimal.ToString() и передайте CultureInfo.InvariantCulture в качестве поставщика формата. –

ответ

1

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

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 

Update: Я использовал строку форматирования согласно ниже, и она работала для меня

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 

enter image description here

enter image description here

+0

К сожалению, похоже, что функция Support.Format не учитывает, что культура изменилась ... –

+0

См. Часть обновления моего ответа, где я делаю форматирование C2 в строковом формате. –

+0

Благодарим вас за то, что на самом деле я удалил эту дрянной ретро-совместимость функции 'Support.Format', поскольку он не принимает ничего, кроме указанных региональных настроек. Вместо этого я использовал 'String.Format()'. –