TOC

This article has been localized into Czech by the community.

WPF aplikace:

Kulturní nastavení aplikace / UICulture

Pokud jste ve WPF už alespoň trošku pracovali s čísly či datem a časem, třebas i díky článkům z tohoto tutoriálu, možná jste si všimli jedné skvělé funkcionality - Čísla a data jsou automaticky zobrazována ve formátu, který odpovídá nastavení celého počítače. Žijete-li v anglicky mluvící zemi, možná vám to ani nepřijde, ale žijete-li v České republice či jiné zemi, ve které se formátuje jinak, než podle anglického způsobu, je to vážně skvělá věc.

Pokud si teď říkáte "Ale notak, přece nemůže existovat až tolik rozdílů ve formátování něčeho tak jednoduchého, jako jsou čísla a data," doporučuji, abyste se podívali na následující ukázkovou aplikaci, ve které jsem stejné číslo a datum naformátoval podle pravidel Spojených Států Amerických (US), Německa (Germany) a Švédska (Sweden):

Jak vám snad příklad ukázal, existuje mnoho drobných rozdílů ve způsobu, jak zobrazovat čísla a data. Dobrá zpráva je, že .NET vám s tímhle umí hodně pomoci - dokonce už tak činí: Při výchozím nastavení aplikace formátuje podle nastavení operačního systému počítače, ve kterém aplikaci spustíte. Špatná zpráva je, že to nemusí být vždycky to, co chcete - není se však třeba obávat, protože se to dá snadno změnit. Klíčovým prvkem je třída CultureInfo,o které se můžete dozvědět více z Tutoriálu pro C#, článek o CultureInfo. My se nyní podíváme na to, jak techniky diskutované v odkazovaném článku použít ve WPF aplikaci.

Formátování lokálně (ad-hoc)

Potřebujete-li aplikovat formátování jen na nějakou dílčí informaci, jako třeba na obsah jednoho Labelu, dá se to jednoduše udělat za běhu s použitím kombinace metody ToString() a třídy CultureInfo. V příkladu výše jsem použil přesně tuto techniku, aplikoval jsem formátování jednotlivě pro každý kus textu, a to tímto způsobem:

double largeNumber = 123456789.42;

CultureInfo usCulture = new CultureInfo("en-US");
CultureInfo deCulture = new CultureInfo("de-DE");
CultureInfo seCulture = new CultureInfo("sv-SE");

lblNumberUs.Content = largeNumber.ToString("N2", usCulture);
lblNumberDe.Content = largeNumber.ToString("N2", deCulture);
lblNumberSe.Content = largeNumber.ToString("N2", seCulture);

Tohle postačí pro pár situací, kde jen potřebujete specifické formátování na pár míst, ale obecně byste se měli rozhodnout, jestli má vaše aplikace použít systémová nastavení (což je výchozí způsob), nebo jestli chcete celé aplikaci udělit pevné kulturní nastavení.

CurrentCulture a CurrentUICulture

Udělit WPF aplikaci jiné kulturní nastavení je velmi jednoduché. Dělá se to skrze dva atributy, na které přistoupíte skrze vlastnost CurrentThread na třídě Thread. Atributy se jmenují podobně CurrentCulture a CurrentUICulture. Jaký je ale mezi nimi rozdíl?

Vlastnost CurrentCulture kontroluje, jak jsou formátována čísla a data. Výchozí hodnotu uděluje operační systém při spuštění aplikace, a lze ji měnit nezávisle na jazyce použitém v operačním systému. Například, osoba žijící v Německu si nainstaluje Windows v angličtině, ale pro čísla a data raději preferuje německou notaci. Pro takovou situaci má CurrentCulture výchozí hodnotu německou.

Vlastnost CurrentUICulture určuje jazyk, kterým by měly být psány texty v grafickém rozhraní. Je tedy relevantní pouze tehdy, kdy má aplikace podporu pro více jazyků, kupříkladu s pomocí jazykových zdrojových souborů (resource souborů .resx). Opět vysvětlíme, že to umožňuje použít jeden jazyk (např. angličtinu) pro texty v aplikaci, a druhý jazyk (např. němčinu) pro výpis a načítání čísel, časových údajů atd.

Změna kulturního nastavení aplikace

Když jsme toto nyní osvětlili, mělo by vám již být jasné, jestli chcete změnit CurrentCulture nebo CurrentUICulture. Můžete to udělat víceméně kde chcete, ale největší smysl to dává udělat při startu aplikace - jinak se může stát, že se nějaký obsah vygeneruje ještě podle výchozí kultury, než dojde k přenastavení. V následujícím příkladu přepneme Culture i UICulture v rámci obsluhy události Application_Startup v souboru App.xaml.cs:

private void Application_Startup(object sender, StartupEventArgs e)
{
    Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
}

Také si nezapomeňte připsat do souboru příslušné direktivy using pro přímé použití tříd Thread a CultureInfo, pokud tam tedy již nejsou:

using System.Threading;
using System.Globalization;

Nyní se budou čísla a data formátovat tak, jak je to zvykem v Německu (de-DE). A jak jsme již říkali, řádku s nastavením UICulture (poslední řádek) je možné vynechat úplně, pokud vaše aplikace nemá podporu pro více jazyků.

Změna kultury v rámci události Application_Startup, či nejpozději v konstruktoru hlavního okna, dává největší smysl, jelikož hodnoty, které již byly vygenerovány nejsou automaticky předělány, když dojde ke změně CurrentCulture. To ale samozřejmě neznamená, že to nemůžete udělat, jak ukazuje následující příklad. Také je to ukázka toho, jak vlastnost CurrentCulture ovlivňuje výstup:

<Window x:Class="WpfTutorialSamples.WPF_Application.ApplicationCultureSwitchSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTutorialSamples.WPF_Application"
mc:Ignorable="d"
Title="ApplicationCultureSwitchSample" Height="200" Width="320">
    <StackPanel Margin="20">
<Grid>
    <Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Label>Number:</Label>
    <Label Name="lblNumber" Grid.Column="1" />
    <Label Grid.Row="1">Date:</Label>
    <Label Name="lblDate" Grid.Row="1" Grid.Column="1" />
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,20">
    <Button Tag="en-US" Click="CultureInfoSwitchButton_Click" HorizontalContentAlignment="Stretch">English (US)</Button>
    <Button Tag="de-DE" Click="CultureInfoSwitchButton_Click" HorizontalContentAlignment="Stretch" Margin="10,0">German (DE)</Button>
    <Button Tag="sv-SE" Click="CultureInfoSwitchButton_Click" HorizontalContentAlignment="Stretch">Swedish (SE)</Button>
</StackPanel>
    </StackPanel>
</Window>
using System;  
using System.Globalization;  
using System.Threading;  
using System.Windows;  
using System.Windows.Controls;  

namespace WpfTutorialSamples.WPF_Application  
{  
    public partial class ApplicationCultureSwitchSample : Window  
    {  
public ApplicationCultureSwitchSample()  
{  
    InitializeComponent();      
}  

private void CultureInfoSwitchButton_Click(object sender, RoutedEventArgs e)  
{  
    Thread.CurrentThread.CurrentCulture = new CultureInfo((sender as Button).Tag.ToString());      
    lblNumber.Content = (123456789.42d).ToString("N2");  
    lblDate.Content = DateTime.Now.ToString();  
}  
    }  
}

Zajímavá část kódu je v obslužné metodě CultureInfoSwitchButton_Click(), kde nastavíme vlastnost CurrentCulture podle toho, které tlačítko bylo zmáčknuto, a po té zaktualizujeme dva Labely, které obsahují číslo a aktuální datum a čas:

Kultura a Vlákna aneb vlastnost DefaultThreadCurrentCulture

Používá-li vaše aplikace více vláken, měli byste zvážit použití vlastnosti DefaultThreadCurrentCulture. Naleznete ji ve třídě CultureInfo (a to od .NET frameworku verze 4.5) a její změnou zajistíte, že zvolené kulturní nastavení se nastaví nejen na aktuální vlákno, ale i na všechna budoucí vlákna. Použije se následujícím způsobem, kupříkladu opět v rámci obsluhy události Application_Startup:

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-DE");

Takže bude potřeba nastavit jak vlastnost CurrentCulture tak DefaultThreadCurrentCulture? Naštěstí ne - pokud jste ještě nenastavili CurrentCulture, pak přenastavením DefaultThreadCurrentCulture se stejně přenastaví i CurrentCulture na současném vlákně. Jinými slovy, je vhodnější použít DefaultThreadCurrentCulture namísto CurrentCulture, a to zejména, pokud budete v aplikaci používat více vláken - pokryjete tak všechny případy.

Shrnutí

Nastavit správně kulturní parametry vaší WPF aplikace je velmi důležité, ale naštěstí také velice jednoduché, protože už ve výchozím nastavení toho spousta funguje sama od sebe správně. Změna výchozího chování je také jednoduchá, a to nastavením vlastností CurrentCulture a CurrentUICulture, jak jsme ilustrovali celou řadou příkladů.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!