2011-09-08 11 views
7

Estoy trabajando en Namibia. Namibia no es una opción en la configuración regional de Windows e Idioma, pero comparte la mayoría de las características culturales con Sudáfrica, por lo que seleccionamos English South Africa y luego personalizar el símbolo de moneda para ser "N $" (dólares namibios) y no "R" "(Rand sudafricano).Cómo utilizar la configuración de región y de idioma personalizada de Windows en WPF

Sin embargo, no puedo convencer a WPF para que use la moneda personalizada. El uso de string.format("{0:c}", foo) en el código funciona bien, pero al usar {Binding Path=SomeCurrencyValue, StringFormat=c} `en XAML todavía se usa el símbolo" R "y no el símbolo" N $ "personalizado.

En App.xaml.cs que establezca la Cultura de la aplicación con el siguiente código:

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))); 

Como demostración, aquí hay un código XAML que muestra el problema:

<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> 

El DataContext para la vista anterior contiene lo siguiente:

public double SomeCurrencyValue 
{ 
    get { return 34.95; } 

} 

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

Y el resu lt es el siguiente: Currency Issue Result

Yo sé que hay una pregunta similar here, pero yo tenía la esperanza de obtener mejores respuestas con una pregunta más completa. Principalmente estoy trabajando en aplicaciones financieras para clientes de Namibia, así que este es un problema bastante serio para mí: si no hay forma de hacerlo con .NET 4.0, consideraría presentar un informe de errores, pero solo quería verificar aquí primero .

EDIT:

acaba de abrir la recompensa por esta pregunta. Espero una solución que no sea una solución alternativa, o la confirmación de que se trata de un error y que se debe archivar como tal.

+0

¿Intentó usar convertidores? esa es una opción para ti? – katie77

+0

Mi problema con el uso de conversores es principalmente que luego tengo que hacer la conversión manualmente: con el formato de cadena en el enlace, la vinculación se ocupa de la entrada del usuario como "N $ 50" o "N $ 5 000 000.00". Hacerlo manualmente no será trivial, a menos que de alguna manera pueda extender el convertidor predeterminado, pero no sé si eso será posible. –

+0

Estaba a punto de publicar una respuesta en la que se puede utilizar la propiedad 'Idioma' para cualquier' FrameworkElement' pero no pude hacerlo funcionar con Namibian Dollars. Lo más parecido que obtuve fue '' pero eso es Namibia English .. Además, no noté ninguna diferencia entre la presentación de moneda de Xaml o el código –

Respuesta

4

Una solución para esto es crear esta CultureInfo de Namibia, por lo que es completamente reconocida por todas las capas .NET. Aquí es un código que lo hace:

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"); 
} 

vez que haya llamado la función del registro de una vez en una máquina determinada (es necesario instalar esta cultura en las máquinas de los usuarios finales), ahora se puede utilizar el código inicial de puesta en marcha de WPF , simplemente cámbialo así:

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

Y todo debería funcionar como se esperaba. También puede usar etiquetas de idioma estándar y todo ese jazz, ya que ahora se reconoce en-NA.

+0

Esto parece MUY prometedor. Haré un esfuerzo para probarlo mañana para poder marcar la respuesta. Gracias –

+0

Hola Simon: He considerado tu respuesta, y aunque creo que mereces la recompensa, no quiero marcarla como respondida. Creo que la pregunta real sigue sin respuesta: "¿Cómo puedo acceder a la moneda personalizada en el Cultura de Windows ". Porque, aunque su respuesta resolverá mi problema, no se generaliza. ¿Qué sucede si el usuario NO es de Namibia o quiere usar su propia configuración personalizada? Windows proporciona una interfaz para personalizar el símbolo de moneda: WPF DEBERÍA proporcionar una interfaz para acceder a esa configuración. Gracias de nuevo, aunque no lo he marcado como respuesta, he votado a favor su respuesta. –

1

Tuve el mismo problema y comencé con la respuesta de Simon (gracias, Simon) haciendo algunas modificaciones para obtener la configuración del usuario (Región e Idioma en el Panel de Control) cada vez que se lanza la aplicación, no el valor cultural predeterminado .

Mi mirada código como éste

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(); 
} 

Funciona bien para mí, pero hay dos problemas en este enfoque:

  1. En 7+ ventanas que necesita para iniciar la aplicación con derechos de administrador ya que creará un nuevo archivo cultural en C: \ Windows \ Globalization con el nombre que le dé a su cultura personalizada
  2. El método Unregister no elimina el archivo creado anteriormente, pero lo renombra como xyz.tmp0 y, con una lógica No lo hice t get, cada cierto tiempo crea más copias de archivos tmp (xyz.tmp1, xyz.tmp2, ...). Al menos así es como funciona en mi pc.

Algo que no es realmente un problema, pero un poco extraño es que, una vez que cambio mi configuración regional en el panel de control, tengo que iniciar mi aplicación dos veces antes de ver la modificación. Puedo sobrevivir :)

Cuestiones relacionadas