2011-09-08 12 views
7

Pracuję w Namibii. Namibia nie jest opcją w ustawieniach regionalnych i językowych systemu Windows, ale łączy je z RPA, więc wybieramy English South Africa, a następnie dostosowujemy symbolem waluty na "N $" (Namibijskie dolary), a nie "R "(Rand południowoafrykański).Jak korzystać z niestandardowych ustawień regionalnych i językowych systemu Windows w WPF

Nie mogę jednak przekonać WPF do korzystania z niestandardowej waluty. Używanie w kodzie string.format("{0:c}", foo) działa dobrze, ale używając {Binding Path=SomeCurrencyValue, StringFormat=c} `w XAML nadal używa symbolu" R ", a nie niestandardowego symbolu" N $ ".

W App.xaml.cs ustawić kultury aplikacji z następującego kodu:

System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.LCID, true); 

FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), 
                 new FrameworkPropertyMetadata(
                  System.Windows.Markup.XmlLanguage.GetLanguage(
                   System.Globalization.CultureInfo.CurrentUICulture.IetfLanguageTag))); 

W demonstracji, tu jest jakiś kod XAML, który pokazuje problem:

<StackPanel> 
    <TextBlock> 
     Formatted in XAML with: <LineBreak/> 
     Text="{Binding Path=SomeCurrencyValue, StringFormat=c}" <LineBreak/> 
     Result: 
    </TextBlock> 

    <TextBox Text="{Binding Path=SomeCurrencyValue, StringFormat=c, Mode=OneWay}" 
      Margin="5"/> 

    <TextBlock> 
     Formatted in code with: <LineBreak/> 
     return string.Format("{0:c}", SomeCurrencyValue); <LineBreak/> 
     Result: 
    </TextBlock> 

    <TextBox Text="{Binding Path=SomeCurrencyString, Mode=OneWay}" 
      Margin="5"/> 

</StackPanel> 

DataContext dla wyżej View zawiera Następujące:

public double SomeCurrencyValue 
{ 
    get { return 34.95; } 

} 

public string SomeCurrencyString 
{ 
    get 
    { 
     return string.Format("{0:c}", SomeCurrencyValue); 
    } 
} 

I do pobrania lt wygląda następująco: Currency Issue Result

wiem, że jest podobna kwestia here, ale miałem nadzieję, aby uzyskać lepsze odpowiedzi z pełniejszego pytanie. Pracuję głównie nad aplikacjami finansowymi dla klientów z Namibii, więc jest to dla mnie poważny problem - jeśli nie ma sposobu, aby to zrobić z .NET 4.0, rozważę zgłoszenie błędu, ale chciałem najpierw sprawdzić tutaj .

EDIT:

Właśnie otworzyła bounty na to pytanie. Mam nadzieję, że albo rozwiązanie, które nie jest drastycznym obejściem, albo potwierdzenie, że jest to błąd i powinno zostać zgłoszone jako takie.

+0

Czy próbowałeś używać konwerterów? Czy to dla ciebie opcja? – katie77

+0

Mój problem z używaniem konwerterów polega przede wszystkim na tym, że muszę ręcznie wykonać konwersję - przy pomocy stringformat w powiązaniu, powiązanie wymaga troski o dane wejściowe użytkownika, takie jak "N $ 50" lub "N $ 5 000 000,00". Robienie tego ręcznie nie będzie trywialne, chyba że mogę w jakiś sposób rozszerzyć domyślny konwerter, ale nie wiem, czy to będzie możliwe. –

+0

Właśnie miałem opublikować odpowiedź, że możesz użyć własności 'Language' dla dowolnego' FrameworkElement', ale nie mogłem jej uruchomić z namibijskimi dolarami. Najbliżej znalazłem '' ale to jest Namibia English .. Również zauważyłem, że nie ma różnicy między prezentacją walutową z Xaml lub kodem –

Odpowiedz

4

Jednym z rozwiązań jest stworzenie tego namibijskiego CultureInfo, tak aby był w pełni rozpoznawany przez wszystkie warstwy .NET. Oto kod, który to robi:

public static void RegisterNamibianCulture() 
{ 
    // reference the sysglobl.dll assembly for this 
    CultureAndRegionInfoBuilder namibianCulture = new CultureAndRegionInfoBuilder("en-NA", CultureAndRegionModifiers.None); 

    // inherit from an existing culture 
    namibianCulture.LoadDataFromCultureInfo(new CultureInfo("en-za")); 
    namibianCulture.CultureEnglishName = "Namibia"; 
    namibianCulture.RegionEnglishName = "Namibia"; 
    namibianCulture.CultureNativeName = "Namibia"; // you may want to change this 
    namibianCulture.RegionNativeName = "Namibia"; // you may want to change this 

    // see http://en.wikipedia.org/wiki/ISO_3166-1, use user-defined codes 
    namibianCulture.ThreeLetterISORegionName = "xna"; // I use x as 'extended' and 'na' as namibia 
    namibianCulture.TwoLetterISORegionName = "xn"; 
    namibianCulture.ThreeLetterWindowsRegionName = namibianCulture.ThreeLetterISORegionName; 

    // see http://www.currency-iso.org/dl_iso_table_a1.xml 
    namibianCulture.ISOCurrencySymbol = "nad"; 
    namibianCulture.CurrencyEnglishName = "Namibia Dollar"; 
    namibianCulture.CurrencyNativeName = "Namibia Dollar"; // you may want to change this 

    // this is were you build something specific, like this symbol you need 
    namibianCulture.NumberFormat.CurrencySymbol = "N$"; 

    // you'll need admin rights for this 
    namibianCulture.Register(); 
} 

public static void UnregisterNamibianCulture() 
{ 
    CultureAndRegionInfoBuilder.Unregister("en-NA"); 
} 

Po nazwali funkcja Rejestracja raz na danej maszynie (trzeba będzie zainstalować tę kulturę na komputerach użytkowników końcowych), można teraz korzystać z początkowego kodu startowego WPF , wystarczy zmienić go tak:

System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-NA"); 

i wszystko powinno działać zgodnie z oczekiwaniami. Możesz również użyć standardowych znaczników języka i całego tego jazzu, ponieważ en-NA jest teraz rozpoznawany.

+0

Wygląda to bardzo obiecująco. Postaram się przetestować go jutro, aby móc zaznaczyć odpowiedź. Dzięki –

+0

Witaj Simon - Potraktowałem twoją odpowiedź, i chociaż myślę, że zasługujesz na nagrodę, nie chcę oznaczać jej jako odpowiedzi - myślę, że prawdziwe pytanie wciąż pozostaje bez odpowiedzi: "Jak uzyskać dostęp do niestandardowej waluty Kultura Windows ". Ponieważ, chociaż twoja odpowiedź rozwiąże mój problem, nie generalizuje - co jeśli użytkownik NIE jest Namibijczykiem, czy chce użyć swoich własnych ustawień? System Windows udostępnia interfejs do dostosowywania symbolu waluty - WPF POWINIEN udostępnić interfejs dostępu do tego ustawienia. Jeszcze raz dziękuję, chociaż nie zaznaczyłem tego jako odpowiedzi, przegłosowałem twoją odpowiedź. –

1

Miałem ten sam problem i zacząłem od odpowiedzi Simona (dziękuję, Simon) wprowadzając pewne modyfikacje, aby uzyskać konfigurację użytkownika (region i język w Panelu sterowania) za każdym razem, gdy aplikacja jest uruchamiana, a nie jako domyślna kultura .

Mój kod wygląda jak ten

public MainWindow() 
{ 
    CreateAndRegisterLocalizedCulture(); 
    this.Language = XmlLanguage.GetLanguage(customCultureName); 

    InitializeComponent(); 

    DataContext = new ViewModel(); 
} 

private void CreateAndRegisterLocalizedCulture() 
{ 
    CultureAndRegionInfoBuilder customCulture = new CultureAndRegionInfoBuilder(customCultureName, CultureAndRegionModifiers.None); 

    // Inherits from the current culture and region, may be configured by the user 
    customCulture.LoadDataFromCultureInfo(CultureInfo.CurrentCulture); 
    customCulture.LoadDataFromRegionInfo(RegionInfo.CurrentRegion); 

    // Not needed for the culture sake but... 
    customCulture.CultureEnglishName = CultureInfo.CurrentCulture.EnglishName + "-Customized"; 
    customCulture.CultureNativeName = CultureInfo.CurrentCulture.NativeName + "-Customized"; 

    // If the custom culture is already registered an unregistration is needed 
    // otherwise the following Register() call will generate an exception 
    if (CultureInfo.GetCultures(CultureTypes.UserCustomCulture).Where(ci => (ci.Name == customCulture)).Count() != 0) 
    { 
     // Admin rights are needed here 
     CultureAndRegionInfoBuilder.Unregister(customCulture); 
    } 

    // Admin rights are needed here 
    customCulture.Register(); 
} 

To działa dobrze dla mnie, ale istnieją dwa problemy w tym podejściu:

  1. W oknach 7+ trzeba uruchomić aplikację z prawami administratora ponieważ utworzy nowy plik kultury w C: \ Windows \ Globalizacja z nazwą nadaną twojej kulturze niestandardowej
  2. Metoda wyrejestrowania nie usuwa powyższego pliku create, ale zmienia jego nazwę jako xyz.tmp0 i, z logiką Ja nie' t get, od czasu do czasu tworzy więcej kopii plików tmp (xyz.tmp1, xyz.tmp2, ...). Przynajmniej tak to działa na moim komputerze.

Coś, co nie stanowi problemu, ale nieco dziwne jest to, że po zmianie ustawień regionalnych w panelu sterowania, muszę uruchomić aplikację dwukrotnie, zanim zobaczę modyfikację. Mogę przeżyć :)

Powiązane problemy