Bạn có thể giới thiệu một cách hay để triển khai hệ thống đa ngôn ngữ cho một ứng dụng WPF không? Phương pháp tôi đang sử dụng hiện nay liên quan đến XML, các lớp và phần mở rộng xaml. Nó hoạt động tốt trong hầu hết các trường hợp, nhưng khi tôi phải đối phó với nhãn động hoặc văn bản động nói chung nó đòi hỏi một số nỗ lực thêm. Tôi muốn cho lập trình viên làm việc chỉ trong vấn đề chính và quên các vấn đề về lang.Đa ngôn ngữ trong WPF
Trả lời
Tôi đang sử dụng WPF Localization Extension. Đó là cách thực sự dễ dàng để bản địa hóa bất kỳ loại nào của DependencyProperty
trên DependencyObject
s.
- đang ở trong một trạng thái ổn định thực
- hỗ trợ ràng buộc giống như phong cách viết như
Text = {LocText ResAssembly:ResFile:ResKey}
- công trình với cơ chế Resx-dự phòng (ví dụ en-us -> en -> văn hóa độc lập)
- hỗ trợ văn hóa buộc (ví dụ"Đây có phải là tiếng Anh mọi lúc")
- công trình với các thuộc tính phụ thuộc bình thường
- công trình với các mẫu kiểm soát
- có thể được sử dụng trong XAML (thực sự: P) mà không cần bất kỳ không gian tên thêm
- có thể được sử dụng trong mã phía sau để ràng buộc các giá trị được bản địa hoá cho các điều khiển được tạo động
- thực hiện
INotifyPropertyChanged
để sử dụng nâng cao - hỗ trợ định dạng chuỗi ví dụ
"this is the '{0}' value"
- hỗ trợ tiền tố và hậu tố giá trị (hiện với
LocText
mở rộng) - được sử dụng trong các hệ thống sản xuất (như sản phẩm nào liên quan của tôi)
- chuyển đổi của ngôn ngữ để thời gian chạy ảnh hưởng NO timeslice
- có thể được sử dụng với bất kỳ tệp tài nguyên nào (
.resx
) trên tất cả các cụm (cũng được tải động khi chạy) - không cần bất kỳ quá trình khởi tạo nào (như "gọi xyz để đăng ký từ điển bản địa hóa đặc biệt") .210
- có sẵn tại thời gian thiết kế (MS Expression Blend, MS Visual Studio 2008 (bình thường và SP1)
- thay đổi ngôn ngữ đã chọn là có thể tại thời gian thiết kế
- có thể khoanh vùng bất kỳ loại kiểu dữ liệu, miễn là bộ chuyển đổi (
TypeConverter
) cho nó tồn tại (kéo dàiLocalizeExtension
) - đã xây dựng trong hỗ trợ cho
Text
, trênText
, thấpText
,Image
s,Brush
es,Double
vàThickness
- không ảnh hưởng đến bất kỳ bộ nhớ bị rò rỉ
- rời khỏi tài sản
UID
bị ảnh hưởng - cung cấp
SpecificCulture
để sử dụng làmIFormatProvider
(ví dụ:(123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20"
hoặc"123,20"
) - cung cấp một số chức năng để kiểm tra và nhận được các giá trị tài nguyên trong mã đằng sau
- không làm thay đổi văn hóa trên
Thread.CurrentCulture
hoặcThread.CurrentUICulture
(có thể được thay đổi một cách dễ dàng)
Thực hiện theo các bước sau:
1) Nơi tất cả String
mảnh trong một tập tin tài nguyên riêng biệt.
Ví dụ: StringResources.xaml
:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<!-- String resource that can be localized -->
<system:String x:Key="All_Vehicles">All Vehicles</system:String>
</ResourceDictionary>
2) Tạo bản sao cho mỗi ngôn ngữ và thêm chúng (dịch) vào từ điển sáp nhập. Đừng quên thêm mã ISO của quốc gia để làm mọi thứ dễ dàng hơn.
Ví dụ App.xaml
:
<Application x:Class="WpfStringTables.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="StringResources.de-DE.xaml" />
<ResourceDictionary Source="StringResources.nl-NL.xaml" />
<ResourceDictionary Source="StringResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Các tập tin tài nguyên cuối cùng với chuỗi sẽ được sử dụng để thay thế phần văn bản trong mã.
3a) Sử dụng các phần văn bản từ bảng String
:
Ví dụ Window1.xaml
:
<Window x:Class="WpfStringTables.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Button Margin="51,82,108,129" Name="AllVehiclesButton"
Content="{StaticResource All_Vehicles}"/>
</Grid>
</Window>
3b) tải các tài nguyên từ mã (Chỉ sử dụng mã này nếu bạn không muốn đặt qua XAML
):
void PageLoad()
{
string str = FindResource("All_Vehicles").ToString();
}
4) Chuyển đến nền văn hóa mới ở đầu ứng dụng:
Codesnippet từ App.xaml.cs
:
public static void SelectCulture(string culture)
{
if (String.IsNullOrEmpty(culture))
return;
//Copy all MergedDictionarys into a auxiliar list.
var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();
//Search for the specified culture.
string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
var resourceDictionary = dictionaryList.
FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
if (resourceDictionary == null)
{
//If not found, select our default language.
requestedCulture = "StringResources.xaml";
resourceDictionary = dictionaryList.
FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
}
//If we have the requested resource, remove it from the list and place at the end.
//Then this language will be our string table to use.
if (resourceDictionary != null)
{
Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
}
//Inform the threads of the new culture.
Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
}
Yêu thích đề xuất của bạn. Những điều cần thêm: Tôi nghĩ chúng ta có thể làm cho ứng dụng có thể chuyển đổi trong thời gian chạy bằng cách sử dụng '{StaticResource resKey}' –
Thực ra, chỉ cần chỉ định {DynamicResource resKey} ở bất cứ nơi nào bạn sử dụng tài nguyên, lúc chạy bất cứ lúc nào, gọi SelectCulture (culture) phương pháp trên và nó sẽ cập nhật tất cả các chuỗi của bạn đến văn hóa mới một cách linh hoạt. Thay vì: string str = FindResource ("All_Vehicles"). ToString(); Sử dụng: Application.Current.Resources ["All_Vehicles"] dưới dạng chuỗi – Curtis
Có cách nào để thay đổi nó trong thời gian thực hiện không? – albatross
Josh Smith đã viết một chiều sâu hướng dẫn về phương pháp ưa thích của mình cho việc này: Creating an Internationalized Wizard in WPF.
Nó có thể hướng bạn đến một thiết kế lại lớn (đó là một MVVM solution), nhưng việc sử dụng MVVM có vẻ đáng giá vì những lý do khác.
Sử dụng bài viết này tôi đã quản lý dễ dàng sử dụng các tệp tài nguyên để xử lý các cửa sổ WPF đa ngôn ngữ. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx Bạn nên kiểm tra vì nó thực sự đơn giản và hiệu quả.
không có tài liệu hoặc hướng dẫn về cách sử dụng? –
tài liệu hiện có sẵn http://wpflocalizeextension.codeplex.com/documentation – SeriousM