實現多國語言有許多種實現方案,無外乎是一種字符串替換技術,將界面控件的文本標籤替換成相應語言的文字。.NET Windows Forms實現多國語言的方法有如下幾種:html
1 .NET的方案,使用資源文件程序員
分別作三個語言的資源文件,好比String.resx,String.zh-cn.resx,String.zh-tw.resx,編譯程序集,運行時用下面的代碼設置程序的語言區域。數據庫
string languageName="zh-cn"; Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(languageName) Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(languageName)
2 使用Xml格式的資源文件緩存
建立Xml格式的資源文件,保存一種或多種語言的字符串,運行時根據用戶所選的語言進行界面標籤字符串替換。app
例子Xml字符串文件以下:ide
<?xml version="1.0"?> <configuration> <add key="Login" Default="Login" zhcn="登陸" zhtw="登錄" /> <add key="UserId" Default="User Id" zhcn="用戶編碼" zhtw="使用者編碼" /> </configuration>
3 數據庫方案工具
將語言資源字符串存放在數據庫中,運行時讀取並替換,這是我推薦的方案。網站
設計語言翻譯數據庫表,用於存放語言翻譯內容,表結構以下:編碼
CREATE TABLE [dbo].[LanguageTranslation] ( [LanguageCode] [nvarchar] (1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [KeyText] [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT, [DisplayText] [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [CreatedDate] [datetime] NULL, [CreatedBy] [nvarchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [RevisedDate] [datetime] NULL, [RevisedBy] [nvarchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ) ON [PRIMARY] GO ALTER TABLE [dbo].[LanguageTranslation] ADD CONSTRAINT [PK_LanguageTranslation] PRIMARY KEY CLUSTERED ([LanguageCode], [KeyText]) ON [PRIMARY] GO EXEC sp_addextendedproperty N'MS_Description', N'翻譯', 'SCHEMA', N'dbo', 'TABLE', N'LanguageTranslation', NULL, NULL GO EXEC sp_addextendedproperty N'MS_Description', N'語言編碼 0 英語 1 繁體中文 2 簡體中文 ', 'SCHEMA', N'dbo', 'TABLE', N'LanguageTranslation', 'COLUMN', N'LanguageCode' GO EXEC sp_addextendedproperty N'MS_Description', N'索引詞', 'SCHEMA', N'dbo', 'TABLE', N'LanguageTranslation', 'COLUMN', N'KeyText' GO EXEC sp_addextendedproperty N'MS_Description', N'顯示詞', 'SCHEMA', N'dbo', 'TABLE', N'LanguageTranslation', 'COLUMN', N'DisplayText' GO EXEC sp_addextendedproperty N'MS_Description', N'建立日期', 'SCHEMA', N'dbo', 'TABLE', N'LanguageTranslation', 'COLUMN', N'CreatedDate' GO EXEC sp_addextendedproperty N'MS_Description', N'創建人', 'SCHEMA', N'dbo', 'TABLE', N'LanguageTranslation', 'COLUMN', N'CreatedBy' GO EXEC sp_addextendedproperty N'MS_Description', N'修改日期', 'SCHEMA', N'dbo', 'TABLE', N'LanguageTranslation', 'COLUMN', N'RevisedDate' GO EXEC sp_addextendedproperty N'MS_Description', N'修改人', 'SCHEMA', N'dbo', 'TABLE', N'LanguageTranslation', 'COLUMN', N'RevisedBy' GO
我以Language Code和相應的字符串爲主鍵,Language Code的值是0,1,2,分別表明英語,繁體,簡體。spa
字符串爲界面控件標籤上的文字,好比User Id, Department等。
爲方便編輯字符串資源,增長一個存儲過程,用於增長和修改語言資源:
SET QUOTED_IDENTIFIER ON SET ANSI_NULLS ON GO CREATE PROCEDURE [dbo].[spAddTranslationText] @KeyText nvarchar(200), @EnglishText nvarchar(200), @ChtText nvarchar(200), @ChsText nvarchar(200) AS BEGIN SET NOCOUNT ON; SET @KeyText = UPPER(@KeyText) DELETE LanguageTranslation WHERE KEYTEXT = @KeyText INSERT LanguageTranslation (LANGUAGECODE, KEYTEXT, DISPLAYTEXT, CREATEDDATE, CREATEDBY, REVISEDDATE, REVISEDBY) VALUES ('0', @KeyText, @EnglishText, GETDATE(), 'MIS', GETDATE(), 'MIS') INSERT LanguageTranslation (LANGUAGECODE, KEYTEXT, DISPLAYTEXT, CREATEDDATE, CREATEDBY, REVISEDDATE, REVISEDBY) VALUES ('1', @KeyText, @ChtText, GETDATE(), 'MIS', GETDATE(), 'MIS') INSERT LanguageTranslation (LANGUAGECODE, KEYTEXT, DISPLAYTEXT, CREATEDDATE, CREATEDBY, REVISEDDATE, REVISEDBY) VALUES ('2', @KeyText, @ChsText, GETDATE(), 'MIS', GETDATE(), 'MIS') END GO
爲了簡化簡體到繁體的轉化,調用.NET VB類庫中的方法,實現簡體轉化爲繁體的功能,簡體轉化爲繁體:
public string ConvertToTraditionalChinese(string label) { return Strings.StrConv(label, VbStrConv.TraditionalChinese, 0); }
基本上知足需求,轉換的準確率不如Word或一些在線翻譯工具。
將存儲過程和語言轉換的方法封裝起來,作成一工具,輸入要翻譯的資源字符串和簡體翻譯,生成存儲過程調用。
程序啓動時,設計一個翻譯資源緩存字典表,分別存放對應語言的鍵值對。
private static Dictionary<int, DataTable> _cachedLanguageTranslation;
如下的代碼從數據庫中讀取翻譯數據到內存中,參考
DataTable languageTable = null; DbFunctionCall isNullDisplayText = new DbFunctionCall("ISNULL", new object[] { LanguageTranslationFields.DisplayText, string.Empty }); EntityField2 displayTextField = new EntityField2("DisplayText", isNullDisplayText); ResultsetFields fields = new ResultsetFields(2); fields.DefineField(LanguageTranslationFields.KeyText, 0, "KeyText"); fields.DefineField(displayTextField, 1, "DisplayText"); ISortExpression sortExpression = new SortExpression(LanguageTranslationFields.KeyText | SortOperator.Ascending); using (DataAccessAdapterBase adapter = GetSystemDataAccessAdapter()) { languageTable = new FastSerializableDataTable(); languageTable.RemotingFormat = SerializationFormat.Binary; IRelationPredicateBucket bucket = new RelationPredicateBucket(); bucket.PredicateExpression.Add(LanguageTranslationFields.LanguageCode == languageCode); bucket.PredicateExpression.Add(displayTextField != string.Empty); bucket.PredicateExpression.Add(LanguageTranslationFields.KeyText != displayTextField); adapter.FetchTypedList(fields, languageTable, bucket, 0, sortExpression, false);
最後,設計一個公共接口方便調用:
//Shared.cs public static string TranslateText(string textToTranslate) { return LanguageTranslator.TranslateText(textToTranslate); }
用數據庫做爲ERP多國語言實現方案有如下幾個緣由:
1 資源字符串能夠被修改。這是最主要的緣由,軟件公司以程序員爲主,沒有實際的行業經驗,不足以恰當(信,達,雅)的設計出各行業的翻譯。產品發佈到客戶後,還能夠修改資源字符串,不合理的地方以用戶的經驗爲主。
2 資源字符串部署。以數據庫表做爲字符串資源的存儲方式,部署時只須要發佈SQL語句文件便可。
INSERT INTO [LanguageTranslation] ([LanguageCode],[KeyText],[DisplayText]) VALUES(N'0', N'-- PRODUCTION REQ --', N'') INSERT INTO [LanguageTranslation] ([LanguageCode],[KeyText],[DisplayText]) VALUES(N'0', N'-- LOC.TOTAL_QTY. --', N'') INSERT INTO [LanguageTranslation] ([LanguageCode],[KeyText],[DisplayText]) VALUES(N'0', N'-- LOC TOTAL_QTY. --', N'') INSERT INTO [LanguageTranslation] ([LanguageCode],[KeyText],[DisplayText]) VALUES(N'0', N'--- JOB ---', N'') INSERT INTO [LanguageTranslation] ([LanguageCode],[KeyText],[DisplayText]) VALUES(N'0', N' DR ', N'') INSERT INTO [LanguageTranslation] ([LanguageCode],[KeyText],[DisplayText]) VALUES(N'0', N' DISC. ALLOWED ', N'') INSERT INTO [LanguageTranslation] ([LanguageCode],[KeyText],[DisplayText]) VALUES(N'0', N'-------------- DEMAND --------------', N'')
寫完了多國語言實現方案,意猶未盡,去Google上搜索一下stackoverflow提供的解決方案,地址是
這篇問答中提到幾個工具,這幾個工具的網站均可以打開,讀者如果在尋找多國語言方案,可實際操做體會一下。
Sisulizer http://www.sisulizer.com/
WPF LocalizationExtension http://wpflocalizeextension.codeplex.com/
GetText http://gnuwin32.sourceforge.net/packages/gettext.htm
DBResource Provider http://www.west-wind.com/presentations/wwDbResourceProvider/