2009-05-02 77 views
19

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

17

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ài LocalizeExtension)
  • đã xây dựng trong hỗ trợ cho Text, trên Text, thấp Text, Image s, Brush es, DoubleThickness
  • 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àm IFormatProvider (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ặc Thread.CurrentUICulture (có thể được thay đổi một cách dễ dàng)
+6

không có tài liệu hoặc hướng dẫn về cách sử dụng? –

+1

tài liệu hiện có sẵn http://wpflocalizeextension.codeplex.com/documentation – SeriousM

32

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

} 
+0

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}' –

+4

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

+0

Có cách nào để thay đổi nó trong thời gian thực hiện không? – albatross

1

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.

Các vấn đề liên quan