TOC

This article has been localized into Vietnamese by the community.

Một ứng dụng WPF:

Application Culture / UICulture

Nếu bạn đã từng làm việc ít nhiều với kiểu số và ngày trong ứng dụng WPF của bạn, và bởi vì một trong những bài viết trong hướng dẫn này bạn có thể để ý thấy một số điều thú vị như: các con số và ngày được tự động hiển thị theo định dạng được sử dụng trên máy tính của bạn. Nếu bạn sống ở đất nước sử dụng tiếng Anh, thì không có điều gì lớn đáng nói, nhưng nếu bạn sống ở NHIỀU quốc gia khác nơi mà kiểu ngày và/hoặc số được hiển thị khác biết, điều ngày thì tuyệt vời.

Và nếu bạn nghĩ rằng "chắc chắn rồi chẳng có nhiều khác biệt khi định dạng những thứ đơn giản như số và ngày?", tôi đề nghị bạn xem xét ứng dụng đơn giản này, khi tôi đã định dạng những con số giống nhau và những kiểu ngày giống nhau để phù hợp với các khư vực như Mỹ, Đức và Thụy Điển:

Bạn có thể thấy rằng, có nhiều khác biệt tinh vi trong cách thể hiện những con số và ngày. Tin tốt là .Net framework có thể giúp bạn rất nhiều - thực tế là nó đã thực hiện: mặc định những ngày và con số được định dạng để phù hợp với cấu hình hệ thống trên máy tính mà ứng dụng của bạn được thực thi. Tin xấu là không phải lúc nào bạn cũng thích điều này. Nhưng không cần phải lo lắng - bạn có thể dễ dàng thay đổi điều này. Tất cả liên quan tới việc sử dụng lớp CultureInfo, bạn có thể đọc nó nhiều hơn trong loạt bài C# Tutorial article on CultureInfo. Bây giờ chúng ta thảo luận cách áp dụng những kỹ thuật này vào ứng dụng WPF của chúng ta.

Định dạng đặc biệt

Nếu bạn chỉ cần áp dụng những định dạng cho một mẫu thông tin, cho nội dung của một Label đơn giản chẳng hạn, bạn có thể dễ dàng làm việc này, sử dụng kết hợp phương thức ToString() và lớp CultureInfo. Chẳng hạn như trong ví dụ ở trên, tôi đã áp dụng những định dạng culture-based khác nhau như:

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

Điều này có thể đủ cho nhiều trường hợp, khi bạn chỉ cần định dạng đặc biệt cho một vài nơi, nhưng nhìn chung, bạn cần quyết định ứng dụng của bạn nên sử dụng cấu hình của hệ thống (mặc định) hay bạn nên override những điều này với một cấu hình nhất định cho toàn hệ thống.

CurrentCulture & CurrentUICulture

Áp dụng culture khác vào ứng dụng của bạn thì tương đối dễ dàng. Có khả năng bạn sẽ xử lý thông qua 2 thuộc tính, thuộc tính CurrentThread được tìm thấy trong lớp Thread: CurrentCultureCurrentUICulture. Nhưng điểm khác biệt là gì?

Thuộc tính CurrentCulture điểu khiển việc các con số và ngày v.v... được hiển thị như thế nào. Giá trị mặc định đến từ hệ điều hành của máy tính thực thi ứng dụng và có thể được thay đổi độc lập với ngôn ngữ được sử dụng bởi hệ điều hành của chúng. Chẳng hạn, thông thường 1 người sống ở Đức cài Windows với ngôn ngữ tiếng Anh cho phần giao diện, trong khi vẫn chọn những quy ước về con số và ngày của người Đức. Cho những trường hợp như thế, thuộc tính CurrentCulture có thể mặc định là tiếng Đức.

Thuộc tính CurrentUICulture chỉ định ngôn ngữ mà giao diện sử dụng. Nó chỉ liên đới khi ứng dụng của bạn hỗ trợ đa ngôn ngữ, chẳng hạn sử dụng resource file cho ngôn ngữ. Một lần nữa, điều này cho phép bạn sử dụng 1 culture cho ngôn ngữ (vd: tiếng Anh), trong khi sử dụng ngôn ngữ khác (vd: tiếng Đức) khi làm việc với việc nhập/xuất các con số, ngày, v.v...

Thay đổi Culture toàn ứng dụng

với những gì đã trình bày, bây giờ bạn phải quyết định khi nào thay đổi CurentCulture và/hoặc CurrentUICulture. Nó có được thực thi bất cứ lúc nào bạn muốn, nhưng hợp lý nhất là áp dụng khi bắt đầu chạy ứng dụng - mặt khác, một vài kết quả có thể được tạo ra với culture mặc định trước khi thực hiện việc chuyển đổi. Sau đây là 1 ví dụ khi nào chúng ta thay đổi Culture, cũng như UICulture, trong sự kiện Application_Startup(), có thể được dùng trong file App.xaml.cs trong ứng dụng WPF của bạn:

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

Khi chúng ta sử dụng lớp Thread cũng như CultureInfo, đừng quên khai báo những namespace nếu chúng chưa có:

using System.Threading;
using System.Globalization;

Với trường hợp này, những con số và ngày sẽ bây giờ sẽ được định dạng theo cách của người Đức (de-DE). Như đã đề cập, ban có thể bỏ qua dòng định nghĩa culture cho UICulture (dòng cuối cùng) nếu ứng dụng của bạn không hỗ trợ đã ngôn ngữ.

Thay đổi culture trong sự kiện Application_Startup, hoặc ở cuối hàm khởi tạo của main window của bạn đều hợp lý, bởi vì những giá trị được tạo ra rồi sẽ không cập nhật tự động khi bạn thay đổi thuộc tính CurrentCulture. Điều đó không có nghĩa rằng bạn không thể làm nó, giống như minh họa ở ví dụ tiếp theo, nó là 1 phụ họa tốt việc kết quả bị ảnh hưởng bởi thuộc tính CurrentCulture:

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

Phần thú vị nhất được tìm thấy trong sự kiện CultureInfoSwitchButton_Click, nơi mà chúng ta thiết lập CurrentCulture dựa trên button được click, và rồi cập nhật vào 2 label chứa số và ngày:

Culture & Threads: Thuộc tính DefaultThreadCurrentCulture

Nếu ứng dụng của bạn sử dụng nhiều hơn 1 thread, bạn nên lưu ý sử dụng thuộc tính DefaultThreadCurrentCulture. Nó có thể được tìm thấy trong lớp CultureInfo (được giới thiệu trong .NET framework 4.5) và sẽ bảo đảm rằng không chỉ thread hiện hành mà còn những thread sau này sẽ sử dụng cùng culture. Bạn có thể sử dụng nó như sau, vd: trong sự kiện Application_Startup:

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

Vậy thì, bạn sẽ thiết lập cùng lúc 2 thuộc tính CurrentCultureDefaultThreadCurrentCulture? Thực tế là không - nếu bạn chưa thay đổi thuộc tính CurrentCulture, thiết lập thuộc tính DefaultThreadCurrentCulture cũng sẽ được áp dụng cho thuộc tính CurrentCulture. Nói cách khác, chỉ hợp lý khi sử dụng DefaultThreadCurrentCulture thay vì CurrentCulture nếu bạn dự định sử dụng nhiều thread trong ứng dụng của bạn - nó sẽ hoạt động tốt trong các kịch bản này.

Tóm tắt

Đối phó với culture trong ứng dụng WPF của bạn là rất quan trọng, nhưng may mắn cho bạn, WPF sẽ làm rất nhiều thứ trong đó và bạn hoàn toàn không cần quan tâm. Nếu bạn cần thay đổi hành vi mặc định, thì nó cũng rất dễ dàng, sử dụng thuộc tính CurrentCultureCurrentUICulture như đã minh họa trong nhiều ví dụ của bài viết này.


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!