Tag Archives: Bản địa hóa ứng dụng Windows Phone

Bản địa hóa ứng dụng Windows Phone 8 XAML – Phần 1

Tạp chí Lập trình – Tác giả bài blog này là Dan Zucker – quản lý chương trình (Program Manager) trong nhóm phát triển Windows Phone.

Đây là Phần 1 của một loạt bài gồm hai phần. Phần 1 sẽ cung cấp cho bạn những hiểu biết sâu hơn về các mô hình chuẩn của việc bản địa hóa một ứng dụng Windows Phone (WP) 8 XAML cùng với một vài bài học kinh nghiệm. Trong Phần 2, tôi sẽ mô tả sức mạnh của “Bộ công cụ cho ứng dụng đa ngôn ngữ”” (Multilingual App Toolkit) sẽ sớm được phát hành cho Windows Phone SDK 8.0, có thể giúp cho quá trình bản địa hóa ứng dụng của bạn dễ dàng hơn.

Vậy là bạn đã quyết định tiến hành bản địa hoá ứng dụng WP của bạn. Có lẽ bạn đã nhận ra (hoặc đã biết) rằng việc làm cho ứng dụng của bạn hỗ trợ nhiều ngôn ngữ sẽ có thể giúp bạn đến được những thị trường lớn hơn và với ít đối thủ cạnh tranh hơn. Mong là bạn đã đọc Những thực tiễn tốt cho việc bản địa hóa WP và Làm thế nào để xây dựng một ứng dụng toàn cầu hóa cho WP cũng như các bài khác trong phần Toàn cầu hóa và nội địa hoá cho WP trên MSDN.

Bạn đã sẵn sàng đưa yếu tố toàn cầu hóa và bản địa hóa vào trong thiết kế ứng dụng của bạn. Vậy làm thế nào bạn có thể tận dụng tốt nhất lợi thế của Windows Phone SDK 8.0?

Có gì mới?

Điều đầu tiên ta nên biết rằng các mẫu dự án mới (project template) cho các ứng dụng XAML cung cấp thêm một số tính năng hữu ích:

  • Khi bạn tạo mới dự án WP trong Visual Studio, bạn đã có sẵn một file tài nguyên chung, thuộc ngôn ngữ trung lập (file AppResources.resx).
  • Có sẵn vài đoạn code mẫu đã được comment lại dành cho việc binding các chuỗi tài nguyên trong XAML.
  • Có sẵn lớp LocalizedStrings – là một lớp hỗ trợ đã được cấu hình để cung cấp mã truy cập dễ dàng đến các tài nguyên phù hợp với ngôn ngữvùng miền hiện tại của ứng dụng.
  • Có sẵn code mẫu về cách bản địa hóa thanh ứng dụng (app-bar), bao gồm cả việc truy cập vào các chuỗi tài nguyên trong code-behind.
  • Mã khởi tạo và các tài nguyên tham số theo ngôn ngữvùng miền cụ thể, đảm bảo rằng phông chữ hiển thị một cách chính xác cho mọi ngôn ngữ (xml:lang và hướng dòng chữ truyền thống được thiết lập một cách rõ ràng cho RootFrame – và nếu đó là không phải là điều bạn muốn, nó có thể được thay đổi dễ dàng).
  • Trong phần Thiết lập thuộc tính dự án (Project Properties) của Visual Studio, khi đăng ký thêm một ngôn ngữ mà bạn dự định hỗ trợ (ở trong phần Supported Culture), một file tài nguyên mới sẽ được tạo ra, với tên file chứa đặc thù của ngôn ngữđịa phương đó, và các thông số khởi tạo cho ngôn ngữvùng miền đó cũng được tạo ra.

CÁC BƯỚC CHUẨN CỦA VIỆC BẢN ĐỊA HÓA

Với danh sách các tính năng mới cho việc bản địa hóa WP trong tay, tôi tạo ra một phiên bản ứng dụng minh họa với ngôn ngữ tiếng Anh được hard-coded, tôi gọi nó là Humanitarian Reader (Ứng dụng đọc tin nhân đạo). Trước khi đi sâu vào việc tinh chỉnh bản địa hóa, hãy cùng xem xét các bước đã được thực hiện để bản địa hoá phiên bản hard-coded này của ứng dụng.


Bắt đầu với data-binding

Như đã đề cập ở trên, đầu tiên tôi tạo ra phiên bản hard-coded ngôn ngữ tiếng Anh của một ứng dụng mẫu. Tiếp theo, tôi dùng data-binding để gắn các thành phần của XAML với tài nguyên dạng chuỗi (string resource). Tôi đã làm điều này bằng cách sao chép mỗi đoạn văn bản được hard-coded (mà tôi mong muốn bản địa hoá) từ trong XAML vào một dòng mới trong bảng tài nguyên của tôi (file AppResources.resx). Đặt cho nó một tên duy nhất.
Sau đó, sửa các thành phần XAML tham chiếu tới các nguồn tài nguyên này bằng cách bổ sung các định danh duy nhất ở trên và đưa các mệnh đề đó vào những vị trí có các giá trị hard-coded. XAML ban đầu trông như sau:

XAML

<TextBlock Text=”Application Title” Style=”{StaticResource PhoneTextNormalStyle}“/>

XAML mới, được ràng buộc với các nguồn tài nguyên bản địa hóa:

XAML

<TextBlock x:Name=”AppTitleTextBlock”

Text=”{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}

            Style=”{StaticResource PhoneTextNormalStyle}“/>

Sau đó tôi tiến hành tìm kiếm trong code-behind những chỗ mà thuộc tính văn bản của một UIElement cần được thay đổi và tiến hành thay thế chuỗi tài nguyên của các phần tử có các giá trị hard-coded với những tham chiếu. Do đó, các mã ban đầu trông như sau:


ApplicationBarMenuItem about_appBarMenuItem = new ApplicationBarMenuItem(“menu item”);

Mã mới, đã được sửa đổi để tham chiếu tới các nguồn tài nguyên bản địa hóa:


ApplicationBarMenuItem about_appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarAboutMenuItem);

Thêm ngôn ngữ

Chắc chắn rằng việc đọc Phần 2 của loạt bài viết này (sẽ sớm ra mắt), ở đó chúng tôi sẽ mô tả về sức mạnh của  Multilingual App Toolkit, bộ công cụ sẽ sớm được phát hành cho Windows Phone 8, có thể được sử dụng để giúp tạo ra các bước sau đây dễ dàng hơn.

Việc thêm ngôn ngữ vào một dự án WP 8 trong Visual Studio khá đơn giản. Tôi mở trang Project Property và lựa chọn các ngôn ngữ mà tôi muốn từ danh Supported Cultures.


Tôi đã thêm tiếng Ả Rập (Saudi Arabia), Trung Quốc (Simplified – giản thể), và tiếng Tây Ban Nha (Spain), có mã vùng miền của chúng lần lượt là ar-SA, zh-Hans, và es-ES. Khi tôi lưu dự án, Visual Studio tạo ra và khởi tạo một bản sao mới của file AppResources.resx cho mỗi ngôn ngữvùng miền.


Các file tài nguyên được khởi tạo như thế nào

Như tôi đã đề cập, việc khởi tạo của một file tài nguyên mới dựa trên việc đưa thông tin ngôn ngữvùng miền vào tên file (với đuôi .resx). Ví dụ, chọn “Tiếng Ả-rập (Saudi Arabia)” thì file tài nguyên AppResources.ar-SA.resx sẽ được tạo. File tài nguyên mới được tạo ra có sẵn các dòng giống với các file hiện có (các file AppResources.resx hiện có).

Trong mỗi file tài nguyên có hai dòng rất đặc biệt tên là ResourceLanguage và ResourceFlowDirection. Hai tài nguyên này được sử dụng khi hàm InitializeLanguage được gọi (từ hàm khởi tạo trong App.xaml.cs). Giá trị của ResourceLanguage và ResourceFlowDirection được kiểm tra tự động để đảm bảo chúng phù hợp với ngôn ngữvùng miền của file tài nguyên đang được nạp (run-time).

Giá trị của ResourceLanguage được khởi tạo với ngôn ngữvùng miền của các file tài nguyên và được sử dụng để thiết lập giá trị cho biến RootFrame.Language. Mục đích là để đảm bảo rằng người dùng sẽ thấy phông chữ đúng cho cả các trường hợp ngôn ngữ Đông Á, khi mà bảng mã Unicode được dùng chồng chéo và hệ thống cần xml:lang để tạo ra chính xác các ký tự. Ví dụ, nếu không chỉ định rõ bảng mã và ngôn ngữ, một ứng dụng tiếng Nhật chạy trên điện thoại với ngôn ngữ chính của máy là Trung Quốc có thể dẫn tới hiển thị một ký tự Trung Quốc ở giữa của một văn bản tiếng Nhật.

Giá trị ResourceFlowDirection được thiết lập là dùng để xác định hướng văn bản truyền thống của ngôn ngữvùng miền. Ví dụ, với tiếng Ả-rập (AppResources.ar-SA.resx ), thứ tự đọc truyền thống là “Từ phải qua trái” (“RightToLeft”).

Lưu ý: Mặc dù ResourceLanguage và ResourceFlowDirection là một phần của mô hình bản địa hóa (mà chúng tôi tin rằng bạn sẽ thấy nó có lợi), bạn luôn có thể sửa đổi các chúng và viết mã nguồn cho phù hợp với phong cách thiết kế của bạn.

Sử dụng máy dịch thuật để dịch (thô) văn bản bản địa hoá

Bây giờ ta đã có một ứng dụng bản địa hóa, trừ phần chuyển đổi các văn bản. Bước tiếp theo là sử dụng Microsoft Translator để có được một bản dịch thô cho mỗi ngôn ngữ. Nhiệm vụ này đã được đơn giản hóa thành một vài cú nhấp chuột, và hầu như không phải chờ đợi, bằng cách sử dụng plug-in Resource Translator
của
Satish Chandra (dành cho Visual Studio 2012). Khi cài đặt, công cụ này cung cấp thêm một mục chọn trong trình đơn khi nhấn chuột phải vào các file .resx.


(Lưu ý: công cụ này có thể sẽ không xử lý được các file .resx khi chúng đang ở trong một thư mục con. Giải pháp là tạm thời di chuyển tập tin resx vào thư mục gốc của dự án, dịch, rồi di chuyển chúng trở lại thư mục Resources.)

Nhờ có công cụ dịch tự động, ta đã có thể thấy rằng bản dịch tiếng Ả Rập sẽ chiếm nhiều chỗ hơn văn bản tiếng Anh, và từ đó tiến hành điều chỉnh kích thước của các thành phần trên giao diện cho phù hợp. Ta cũng có thể dễ dàng nhìn thấy rằng ngôn ngữ hiển thị, dòng văn bản, và việc điều hướng của ứng dụng này đã thay đổi như mong đợi; bạn có thể nghĩ việc này như thể ta đã đáp ứng được một trong số những cách làm tốt được biết đến trong pseudolocalization.

Bản dịch (mịn) do người dịch

Máy dịch thuật càng ngày càng tiến bộ. Điển hình là khi máy có thể đưa ra gợi ý và cho phép tác giả lựa chọn một trong nhiều nghĩa khác nhau có thể có của một văn bản. Với những tiến bộ này, chất lượng và tính nhất quán của bản dịch máy có thể sẽ sớm trở nên đủ tốt cho nhiều dự án. Dù vậy, vẫn cần sự hiện diện của một người thông thạo trong cả ngôn ngữ của bản gốc và các bản dịch. Trong những lĩnh vực đặc thù (của ứng dụng của bạn), hoặc khi cần sự nhạy cảm văn hóa và chính trị của một khu vực, có thể sẽ còn rất lâu phần mềm mới bắt kịp với con người.

Tôi đã có thể thông qua crowdsource để dịch các bản dịch của tôi (Microsoft là một nơi rất quốc tế và các đồng nghiệp của tôi rất hào phóng với thời gian của họ!). Chỉ đơn giản là gửi file resx cho các tình nguyện viên và thay thế bản dịch máy với bản dịch do con người dịch.

Việc phải tìm kiếm và chi trả cho những người dịch thuật khiến nhiều người không bản địa hóa ứng dụng của họ, nhưng điều này đang dần trở nên dễ dàng hơn. Ngày càng có nhiều lựa chọn cho việc dịch thuật trên mạng, từ crowdsource miễn phí cho tới các công ty dịch thuật thương mại lớn.

TÙY CHỈNH BẢN ĐỊA HÓA

XAML và code-behind cần thiết cho việc bản địa hóa một ứng dụng sẽ khác biệt dựa trên tính năng và thiết kế của ứng dụng đó. Đối với Humanitarian Reader, ứng dụng này cần làm 2 điều cơ bản: sử dụng ngôn ngữvùng miền do người dùng đã lựa chọn Phone Language trong
Settings khi lần đầu tiên chạy ứng dụng, và cho phép người dùng chọn một ngôn ngữ khác ngay cả khi ứng dụng đang chạy.

Để hệ thống quyết định ngôn ngữ hiển thị

Phương thức chính giúp duy trì ngôn ngữ của ứng dụng trong thời gian chạy là SetUILanguage, nó nhận một tham số về mã ngôn ngữvùng miền (VD: “en-US”). Để luôn luôn sử dụng thiết lập Phone Language do người dùng chọn, tôi chỉ đơn giản tuân theo cách thức của hệ thống, vì vậy khi chạy ứng dụng tôi khởi tạo ngôn ngữ giao diện người dùng bằng cách sử dụng chính ngôn ngữ hiện tại:


// xử lý mục trình đơn để thay đổi ngôn ngữ ứng dụng sang Trung Quốc (Trung Quốc).
private void zh_appBarMenuItem_Click(object sender, EventArgs e)
{
    SetUILanguage(“zh-CN”);
}

Lựa chọn Phone Language là một trong bốn tài nguyên về ngôn ngữ đã được chuyển đổi ở trên, cùng với hướng văn bản và phông chữ. Nếu người dùng đã lựa chọn ngôn ngữ khác với những ngôn ngữ mà ứng dụng hỗ trợ, hệ thống sẽ sử dụng ngôn ngữ trung lập của ứng dụng, trong trường hợp này là tiếng Anh Mỹ.

Chỉ định một số văn bản luôn luôn cố định một ngôn ngữ

Thanh trình đơn ứng dụng (Application Bar) là một trong các thành phần mà tôi KHÔNG muốn bản địa hoá. Trong thiết kế của tôi, người dùng chọn ngôn ngữ hiển thị của họ thông qua các trình đơn Application Bar. Tôi muốn người dùng thông thạo một ngôn ngữ nào đó có thể xem các mục chọn trong trình đơn cho ngôn ngữ bản địa của họ bất kể hiện thời giao diện đang được hiển thị ở ngôn ngữ nào.

Lưu ý trong hình minh họa dưới đây, tiếng Ả-rập, Trung Quốc, tiếng Anh, và Tây Ban Nha không đổi trong mọi ngôn ngữ hiển thị, trong khi mục “about” được bản địa hóa.


Để thực hiện điều này, ta chỉ cần hard-coded giá trị của các mục lựa chọn ngôn ngữ trong trong phương thức BuildLocalizedApplicationBar, phương thức
dùng để tạo ra các mục chọn ApplicationBarMenuItems bản địa hóa khi ứng dụng chạy và bất cứ khi nào ta thay đổi ngôn ngữ hiển thị:


private void BuildLocalizedApplicationBar()
{
	// Tạo mới đối tượng ApplicationBar.
	ApplicationBar = new ApplicationBar();
	// Tạo các trình đơn với hard-code dành cho các ngôn ngữ
	// Những thứ này không bản địa hóa
	ApplicationBarMenuItem ar_appBarMenuItem = new ApplicationBarMenuItem(“العربية“);
	ApplicationBar.MenuItems.Add(ar_appBarMenuItem);
	ar_appBarMenuItem.Click += new EventHandler(ar_appBarMenuItem_Click);
	ApplicationBarMenuItem zh_appBarMenuItem = new ApplicationBarMenuItem(“中文“);
	ApplicationBar.MenuItems.Add(zh_appBarMenuItem);
	zh_appBarMenuItem.Click += new EventHandler(zh_appBarMenuItem_Click);
	ApplicationBarMenuItem en_appBarMenuItem = new ApplicationBarMenuItem(“english”);
	ApplicationBar.MenuItems.Add(en_appBarMenuItem);
	en_appBarMenuItem.Click += new EventHandler(en_appBarMenuItem_Click);
	ApplicationBarMenuItem es_appBarMenuItem = new ApplicationBarMenuItem(“español“);
	ApplicationBar.MenuItems.Add(es_appBarMenuItem);
	es_appBarMenuItem.Click += new EventHandler(es_appBarMenuItem_Click);
}

Mục “About” cần được ràng buộc với file tài nguyên để thay đổi theo sự lựa chọn của người sử dụng.


      ApplicationBarMenuItem about_appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarAboutMenuItem);
      ApplicationBar.MenuItems.Add(about_appBarMenuItem);

Cho phép người dùng thay đổi ngôn ngữ khi đang chạy ứng dụng

Khi người dùng nhấn vào một ngôn ngữ trong trình đơn Application Bar, phương thức SetUILanguage lại một lần nữa được gọi với mã ngôn ngữvùng miền được chọn. VD, nếu người sử dụng nhấn vào “中文” (Tiếng Trung Quốc), các mã sau sẽ thiết lập ngôn ngữ:


// xử lý mục trình đơn để thay đổi ngôn ngữ ứng dụng sang Trung Quốc (Trung Quốc).

private void zh_appBarMenuItem_Click(object sender, EventArgs e)

{

    SetUILanguage(“zh-CN”);

}

Đầu tiên hàm SetUILanguage đổi lại giá trị CurrentUICulture của ứng dụng thành ngôn ngữvùng miền mà người dùng vừa chọn.


     // Thiết lập lại ngôn ngữ hiện tại của thread này
     CultureInfo newCulture = new CultureInfo(locale);
     Thread.CurrentThread.CurrentCulture = newCulture;
     Thread.CurrentThread.CurrentUICulture = newCulture;

Từ thời điểm này, bất kỳ văn bản nào có gắn ràng buộc với tài nguyên bản địa hóa sẽ sử dụng các nguồn tài nguyên của ngôn ngữ vừa được chọn. Việc tiếp theo là sử dụng các thông số trong file tài nguyên của ngôn ngữ đó để thiết lập FlowDirection và Language cho RootFrame, để cho bất kỳ giao diện mới được tạo ra sẽ áp dụng các thiết lập này.


     //Thiết lập FlowDirection của RootFrame để phù hợp với ngôn ngữ mới.
     FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection),
     AppResources.ResourceFlowDirection);
     App.RootFrame.FlowDirection = flow;
     //Thiết lập ngôn ngữ của các RootFrame để phù hợp với ngôn ngữ mới.
     App.RootFrame.Language = XmlLanguage.GetLanguage(AppResources.ResourceLanguage);

Có một vấn đề là MainPage.xaml đã sẵn sàng được tạo ra, vì vậy hàm SetUILanguage cần làm một vài việc để các thành phần hiện đang được hiển thị được vẽ lại với ngôn ngữ mới. Trước hết nó tìm kiếm các chuỗi tài nguyên đã được chuyển đổi ngôn ngữ cho các phần tử XAML và chuyển các ngôn ngữ của các phần tử đó khớp với địa phương mà SetUILanguage đã thiết lập:


	// Sửa đổi ngôn ngữ của mỗi yếu tố giao diện và thiết lập cho nó ngôn ngữ mới.
	AppTitleTextBlock.Language = XmlLanguage.GetLanguage(locale);
	AppTitleTextBlock.Text = AppResources.ApplicationTitle;
	PageTitleTextBlock.Language = XmlLanguage.GetLanguage(locale);
	PageTitleTextBlock.Text = AppResources.PageTitle;
	MissionTextBlock.Language = XmlLanguage.GetLanguage(locale);
	MissionTextBlock.Text = AppResources.MissionText;
	GoToNewsTextBlock.Language = XmlLanguage.GetLanguage(locale);
	GoToNewsTextBlock.Text = AppResources.GoToNews;
	DisclaimerTextBlock.Language = XmlLanguage.GetLanguage(locale);
	DisclaimerTextBlock.Text = AppResources.DisclaimerText;

Thay đổi FlowDirection (hướng văn bản)

Nhiệm vụ còn lại là kiểm tra hướng hiển thị văn bản hiện tại và thay đổi các yếu tố xung quanh nếu cần.

Thay đổi FlowDirection của RootFrame làm cho cách bố trí của tất cả các thành phần trong XAML của ứng dụng ngay lập tức chuyển hướng hiển thị văn bản. Nếu thay đổi hướng thành “Phải qua trái” (RightToLeft – RTL) thì ngay lập tức, không cần làm gì thêm, văn bản trong các thành phần sẽ hiển thị từ phải sang trái và căn chỉnh theo quy tắc RTL (văn bản vốn đang được hiển thị từ trái qua phải sẽ chuyển hướng từ phải qua trái). Ngoài ra, bố trí tương quan của những thành phần trên trang cũng sẽ thay đổi.

Lưu ý: Mặc dù không cần thêm bất kỳ dòng code nào, logo, tiêu đề ứng dụng, và tiêu đề trang vẫn chuyển hướng một cách thích hợp.


Sự hỗ trợ có sẵn này giúp đơn giản hóa việc áp dụng bản địa hóa vào ứng dụng của bạn. Hy vọng bạn sẽ đồng ý. Tuy nhiên, vẫn có một vấn đề nữa: thay đổi hướng hiển thị văn bản cũng thay đổi việc điều hướng của ứng dụng. Xem trên hình trên, bạn sẽ nhận ra rằng trong trường hợp này tôi muốn hai hình mũi tên ngược chiều nhau cho cùng một nút điều hướng. Tôi cần một mũi tên LTR chỉ để phù hợp với trang tiếp theo, một mũi tên RTL chỉ vào bên trái cũng cho mục đích đó, nhưng dùng trong trường hợp RTL, và mã để chuyển đổi chúng khi FlowDirection thay đổi:


	// Thay đổi hình mũi tên tùy thuộc vào FlowDirection
	bool isFlowRTL = AppResources.ResourceFlowDirection = “RightToLeft” ? true : false;
	if (isFlowRTL)
	{
		GoToNewsImage.Source = new BitmapImage(new Uri(“Assets/rtlGoToNews.png”, UriKind.RelativeOrAbsolute));
	}
	else{
		GoToNewsImage.Source = new BitmapImage(new Uri(“Assets/ltrGoToNews.png”, UriKind.RelativeOrAbsolute));
	}

Thiết lập ngôn ngữ cho RSS (ánh xạ tới ngôn ngữ hiện hành của ứng dụng)

Cuối cùng, phương thức SetUILanguage ánh xạ ngôn ngữ hiện tại của ứng dụng thành mã ngôn ngữ với ba ký tự được dùng để tạo ra URL cho RSS:


// Thiết lập các biến ngôn ngữ RSS để phù hợp với ngôn ngữ của ngôn ngữ mới
switch (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.ToString())
{
    case “ar”: RSSLocale = “ara”; break;
    case “zh”: RSSLocale = “chi”; break;
    case “en”: RSSLocale = “eng”; break;
    case “es”: RSSLocale = “spa”; break;
}

FlowDirection và việc điều hướng trong trình duyệt web

Trang Article của ứng dụng này hiển thị các dữ liệu RSS mà khi nhấn vào sẽ mở ra trình duyệt. Trang trình duyệt được mở ra sẽ chứa một đối tượng trình duyệt web để hiển thị HTML, cũng như hai mũi tên trái và phải cho chức năng “trở lại” và “đi tiếp”. Đây là một trường hợp điển hình của việc điều hướng đảo ngược khi chuyển đổi FlowDirection. Đối với hướng văn bản RTL mũi tên bên trái là “đi tiếp” và mũi tên bên phải là “trở lại”, đối với hướng văn bản LTR hai mũi tên đó có chức năng đảo ngược lại.


Trong trường hợp này, tôi sửa đổi phương thức điều khiển chuyển hướng (BrowserNav), để nó nhận một tham số hướng (dir). BrowserNav sẽ được gọi khi các mũi tên được nhấn, và giá trị của “dir” điều kiện dựa trên hướng hiển thị văn bản hiện tại:


bool isFlowRTL = AppResources.ResourceFlowDirection == “RightToLeft” ? true : false;

Sau đó, tôi sử dụng nó để xác định giá trị hướng cho phương thức BrowserNav:


private void Button_Click_LeftBrowseArrow(object sender, RoutedEventArgs e)
{
    string dir = isFlowRTL ? “forward” : “backward”;
    BrowserNav(dir);
}

private void Button_Click_RightBrowseArrow(object sender, RoutedEventArgs e)
{
    string dir = isFlowRTL ? “backward” : “forward”;
    BrowserNav(dir);
}

CÁC TÁC Đv(dir); ? BrowseArrow(ịnh giá trị hướng ị của “dir” điều k – SERVICE-PROVIDED)

Cuối cùng, hãy nhớ định dạng nội dung là quan trọng. Dưới đây là một vài vấn đề tôi gặp phải, mặc dù đã nghiên cứu kỹ lưỡng các định dạng nội dung của nguồn cấp dữ liệu RSS mà các ứng dụng sử dụng.

Nội dung trong trình duyệt và FlowDirection

Như đã đề cập ở trên, thiết lập FlowDirection cho RootFrame ảnh hưởng đến tất cả các thành phần trong ứng dụng, bao gồm cả thành phần WebBrowser. Trong nhiều trường hợp việc này có thể không ảnh hưởng gì, nhưng lưu ý rằng nội dung web có thể đã có FlowDirection riêng của mình, được đưa ra bởi trình duyệt. Đây là trường hợp với một số trang được hiển thị trong ứng dụng của tôi. Khi đó, việc thiết lập  RootFrame.FlowDirection khiến cho hướng hiển thị văn bản trên trang web ngược lại so với dự định.

Bởi vì các đặc tính như FlowDirection có thể được ghi đè ở bất kỳ điểm nào, giải pháp khá đơn giản: hard-coded giá trị FlowDirection của WebBrowser trong XAML:


&lt;phone:WebBrowser Grid.Row=“1″ Name=“webBrowser1″ FlowDirection=“LeftToRight” Navigated=“webBrowser1_Navigated” Margin=“0,17,0,28″ Grid.RowSpan=“2″ BorderThickness=“1″/&gt;

Định dạng dữ liệu RSS và vấn đề với việc toàn cầu hóa của lớp XMLReader

Có một mâu thuẫn thú vị khác giữa các định dạng dữ liệu RSS và lựa chọn thiết kế ứng dụng: Trang Article hiển thị nội dung dữ liệu từ RSS, dưới dạng một tiêu đề liên kết và một khối văn bản mô tả. Nguồn dữ liệu RSS được phân tích và kết xuất bằng cách sử dụng lớp XMLReader, mặc dù nó không hỗ trợ đầy đủ trong Windows Phone, nó được dùng trong code mẫu của chúng tôi như là một cách nhanh chóng và dễ dàng để làm một ứng lấy dữ liệu RSS. Và, nó hoạt động tốt cho tiếng Anh.

Tuy nhiên, một điều xảy ra đó là định dạng dữ liệu RSS mà tôi sử dụng không minh bạch. Đặc tả RSS 2.0 cần mã tháng gồm 3 ký tự. Trong dữ liệu RSS tiếng Ả-Rập và Trung Quốc cung cấp một dạng mã tháng mà XMLReader không thể hiểu và chuyển sang đối tượng ngày tháng được. Dữ liệu có định dạng ngày tháng đầy đủ, nhưng XMLReader không thấy. Giải pháp: tốt nhất là gắn bó với sự linh hoạt và hỗ trợ đầy đủ LINQ to XML để phân tíchchiết suất dữ liệu RSS bản địa hóa.

Vâng, đó là tất cả những gì dành cho blog này, và thêm một lần nữa tìm lại bản thân mình, mời bạn đọc tiếp Phần 2 để tìm hiểu về cách mà tôi đã sử dụng Multilingual App Toolkit
(được phát hành cho Windows Phone SDK 8.0) để triển khai bản địa hóa ứng dụng Humanitarian Reader Windows Phone 8.

Bài viết được dịch từ nguồn: blogs.windows.com

Người dịch: HoàngTG