2012-02-05 48 views
1

現在,爲了適應像丹麥語這樣的語言中逗號作爲小數佔位符的使用,我檢索用小數點存儲的值,例如, 」 0.123" 從這樣的.resx文件:是否有更好的方法來處理跨語言的雙重值?

// Getting a value from a .resx parameter 
double minValue = Convert.ToDouble(AppParams.minVal, CultureInfo.InvariantCulture); 

當我需要從一個TextBox,例如接收的值工作」 321" 我用這個:

// Getting a value from a TextBox  
double newValue = Convert.ToDouble(value, CultureInfo.CurrentCulture); 

在.csproj的文件,我已經添加<SupportedCultures>da;</SupportedCultures>但在其他方面並沒有試圖應對這兩個問題,不是什麼顯示的其他的一些應用廣泛的方式。

回答

0

我非常感謝Thomas Levesque和lukas的回答。他們包含了一些有用的見解和例子。我發佈這個答案是因爲我想提供更多信息和示例解決方案。與許多計算/用戶界面問題一樣,常常必須作出妥協。我發現了一個不幸的發現,那就是當改變區域+語言設置時,InputScopeNameValues(MSDN InputScopeNameValue Enumeration)在十進制(。)和逗號(,)之間切換(並且,我仔細檢查了手機上的鍵盤設置爲僅使用德語)。

enter image description here

然而,由於這些文本框輸入的數值,需要迅速進入,數字InputScopes仍然以最好的一段路要走。有趣的是,即使用戶被迫使用小數點代替逗號,只要輸入到文本框中,字符串格式就會改變,例如,即使如「{0:#。000}」所示,從「.123」到「,123」也是如此。因此,妥協和在下面的代碼中,解決方法(到目前爲止在en-US和de-DE中進行了測試)。

注意:正如lukas提到的那樣,驗證用戶輸入總是明智的。我沒有在這裏使用TryParse(儘管我可能),所以我不必重寫很多代碼。這是在UI通過選擇一個數字InputScope並通過try/catch塊的處理代碼,甚至正確處理減輕用戶試圖通過從剪貼板粘貼文本,以繞過數字輸入:

<TextBox x:Name="myTBox" InputScope="Number" Text="{Binding SomeNumber, Mode=TwoWay}" /> 

和代碼:

public string SomeNumber 

{ 得到 { 回報的String.Format( 「{0:#000}」,SomeProfileModel.Instance.SomeProfile.SomeNumber); }

set 
{ 
    if (SomeProfileModel.Instance.SomeProfile.SomeNumber.ToString() == value) return; 

    var oldValue = SomeProfileModel.Instance.SomeProfile.SomeNumber; 

    try 
    { 
     double newValue; 

     try 
     { 
      newValue = Convert.ToDouble(value, CultureInfo.CurrentCulture); 
     } 
     catch (Exception) 
     { 
      newValue = Convert.ToDouble(value, CultureInfo.InvariantCulture); 
     } 

     if (Convert.ToDouble(MyAppParams.SomeNumberMin, CultureInfo.InvariantCulture) > newValue || Convert.ToDouble(MyAppParams.SomeNumberMax, CultureInfo.InvariantCulture) < newValue) 
     { 
      // Revert back to previous value 
      // NOTE: This has to be done here. If done in the catch statement, 
      // it will never run since the MessageBox interferes with it. 
      throw new Exception(); 
     } 

     SomeProfileModel.Instance.SomeProfile.SomeNumber = newValue; 

     RaisePropertyChanged("SomeNumber", oldValue, newValue, true); 
    } 
    catch (Exception err) 
    { 
     System.Windows.MessageBox.Show("Value must be a number between " + MyAppParams.SomeNumberMin + " and " + MyAppParams.SomeNumberMax); 
    } 
} 

}

4

你並不需要將值存儲爲RESX文件的字符串:

<data name="minVal" type="System.Double, mscorlib"> 
    <value>.123</value> 
</data> 

這種方式產生的minVal屬性爲double類型,你就不必把它手動轉換。

此方法的唯一問題是您必須手動編輯XML中的resx文件,因爲資源設計人員無法處理此類資源(實際上您可以重命名,刪除資源或更改其值,但你不能改變它的類型,你不能創建一個新的)。無論如何,自從我開始使用Resharper以來,我已經切換到手動編輯resx文件,因爲它爲這些文件提供了一些很好的分析和重構功能;)

作爲一個附註,我不認爲這個minValue常數是一個很好的資源候選人。如果它是可以更改的設置,請將其置於設置中,而不是資源中。如果它真的是一個常量,請在C#代碼中將其設置爲const。將資源投入資源的唯一好理由是,如果您希望價值是可本地化的,並且在這種情況下似乎不太可能。

1

當您從用戶輸入中解析字符串時,嘗試接受許多可能的輸入,例如

public static class Helper 
{ 
    public static bool TryParseDouble(this TextBox textbox, out double value) 
    { 
     if (double.TryParse(textbox.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out value)) 
     { 
      textbox.Foreground = Brushes.Black; //indicates that the user typed correct number 
      return true; 
     } 
     else 
     { 
      textbox.Foreground = Brushes.Red; // not a number 
      return false; 
     } 
    } 
} 

當你解析.resx,XML和其他文件也使用InvariantCulture。 Here是我遇到的XML解析器遇到的問題。

向用戶顯示數據時使用當前文化。