解析大型.NET ERP系统 多国语言实现
实现多国语言有许多种实现方案,无外乎是一种字符串替换技术,将界面控件的文本标签替换成相应语言的文字。.NET Windows Forms实现多国语言的方法有以下几种:
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格式的资源文件,保存一种或多种语言的字符串,运行时根据用户所选的语言进行界面标签字符串替换。
例子Xml字符串文件如下:
<?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,分别代表英语,繁体,简体。
字符串为界面控件标签上的文字,比如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/
相关文章
- Mysql net start mysql启动,提示发生系统错误 5 拒绝訪问 解决之道
- 我做的百度飞桨PaddleOCR .NET调用库 我做的百度飞桨PaddleOCR .NET调用库
- ASP.NET MVC Overview
- CruiseControl.net
- .NET Framework 系统要求
- C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入
- 【ASP.NET MVC系列】浅谈ASP.NET 页面之间传值的几种方式
- Word控件Spire.Doc 【Table】教程(8): 将内置表格样式应用于 C#、VB.NET 中的现有 Word 表格
- 【TechEmpower】21轮Web框架性能评测,.NET第7Spring第67
- c# , .net 后端判断是否是移动端,是否是安卓设备,是否是微信,是否是支付宝,是否是QQ,是否是安卓系统,是否是苹果系统等
- Windows系统服务器IIS7.5 Asp.net支持10万请求的设置方法
- mongodb and .net
- 让使用SQLite的.NET应用自适应32位/64位系统
- 《精通 ASP.NET MVC 3 框架(第三版)》----2.2 准备服务器
- 基于ASP.NET+SQL Server实现(Web)排球赛事网站【100010297】
- 基于ASP.NET+MySQL实现待办任务清单系统【100010180】
- ASP.NET Web API 数据提供系统相关类型及其关系
- asp.net 中给gridview添加自动序号
- Asp.Net Core 获取配置系统Configuration
- .Net魔法堂:开启IIS的WebGarden、WebFarm和StateServer之旅
- 开源倾情奉献:基于.NET打造IP智能网络视频监控系统(三)命令行工具集
- [.Net Core] Visual Studio for Mac Add Client Side Library
- Winform自动更新之AutoUpdater.NET
- .Net 5.0 通过IdentityServer4实现单点登录之授权部分源码解析
- .net下 本地锁、redis分布式锁、zk分布式锁的实现
- 怎么解决xp系统不能安装NET Framework4.0?