解析大型.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/
解析大型.NET ERP系统 多国语言实现的更多相关文章
- 解析大型.NET ERP系统 十三种界面设计模式
成熟的ERP系统的界面应该都是从模板中拷贝出来的,各类功能的界面有规律可遵循.软件界面设计模式化或是艺术性的创作,我认可前者,模式化的界面客户容易举一反三,降低学习门槛.除了一些小部分的功能界面设计特 ...
- 解析大型.NET ERP系统架构设计 Framework+ Application 设计模式
我对大型系统的理解,从数量上面来讲,源代码超过百万行以上,系统有超过300个以上的功能,从质量上来讲系统应该具备良好的可扩展性和可维护性,系统中的功能紧密关联.除去业务上的复杂性,如何设计这样的一个协 ...
- 解析大型.NET ERP系统 设计异常处理模块
异常处理模块是大型系统必备的一个组件,精心设计的异常处理模块可提高系统的健壮性.下面从我理解的角度,谈谈异常处理的方方面面.我的设计仅仅限定于Windows Forms,供参考. 1 定义异常类型 . ...
- 解析大型.NET ERP系统 电子邮件系统帐户集成
为保证ERP系统的信息流准确快速的传递,需要给系统设计一个消息盒子机制.当系统中发生业务操作后,需要提醒下一个环节的操作人员,以保证ERP信息流快速准确传递.比如生产任务单(工作单,加工单,制单)过帐 ...
- 解析大型.NET ERP系统 权限模块设计与实现
权限模块是ERP系统的核心模块之一,完善的权限控制机制给系统增色不少.总结我接触过的权限模块,以享读者. 1 权限的简明定义 ERP权限管理用一句简单的话来说就是:谁 能否 做 那些 事. 文句 含义 ...
- 解析大型.NET ERP系统 通用附件管理功能
大型系统具备一个通用的附件管理功能,对于单据中无法清晰表达的字段,用一个附件图片或附件文档表示是最好的方法了.比如物料清单附加一张CAD图纸,销售订单评审功能中附加客户的各种表格,通用附件功能对系统起 ...
- 解析大型.NET ERP系统核心组件 查询设计器 报表设计器 窗体设计器 工作流设计器 任务计划设计器
企业管理软件包含一些公共的组件,这些基础的组件在每个新项目立项阶段就必须考虑.核心的稳定不变功能,方便系统开发与维护,也为系统二次开发提供了诸多便利.比如通用权限管理系统,通用附件管理,通用查询等组件 ...
- 解析大型.NET ERP系统 20条数据库设计规范
数据库设计规范是个技术含量相对低的话题,只需要对标准和规范的坚持即可做到.当系统越来越庞大,严格控制数据库的设计人员,并且有一份规范书供执行参考.在程序框架中,也有一份强制性的约定,当不遵守规范时报错 ...
- 解析大型.NET ERP系统 单据编码功能实现
单据编码是ERP系统中必备的功能,用于生成各种单据的流水号,常常借助于日期时间等字符来生成一个唯一的单据号码.从软件的角度来说,就是为生成数据表的主键值(参考编号),从用户的角度来说,就是给业务单据制 ...
随机推荐
- 微软.NET Core RC2正式发布,横跨所有平台
.NET官方博客宣布了<Announcing .NET Core RC2 and .NET Core SDK Preview 1>,正式如期发布了.NET Core RC2, 现在可以放心 ...
- 用游标实现查询当前服务器所有数据库所有表的SQL
declare @name varchar(100) DECLARE My_Cursor CURSOR --定义游标 FOR (SELECT Name FROM Master..SysDatabase ...
- 【用户交互】APP没有退出前台但改变系统属性如何实时更新UI?监听系统广播,让用户交互更舒心~
前日,一小伙伴问我一个问题,说它解决了半天都没解决这个问题,截图如下: 大概楼主理解如下: 如果在应用中有一个判断wifi的开关和一个当前音量大小的seekbar以及一个获取当前电量多少的按钮,想知道 ...
- Autofac - MVC/WebApi中的应用
Autofac前面写了那么多篇, 其实就是为了今天这一篇, Autofac在MVC和WebApi中的应用. 一.目录结构 先看一下我的目录结构吧, 搭了个非常简单的架构, IOC(web), IBLL ...
- JSP 标准标签库(JSTL)
JSP 标准标签库(JSTL) JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签, ...
- 关键帧动画:@keyframes
关键帧动画:@keyframes: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- Zabbix 漏洞分析
之前看到Zabbix 出现SQL注入漏洞,自己来尝试分析. PS:我没找到3.0.3版本的 Zabbix ,暂用的是zabbix 2.2.0版本,如果有问题,请大牛指点. 0x00 Zabbix简介 ...
- Kotlin与Android SDK 集成(KAD 05)
作者:Antonio Leiva 时间:Dec 19, 2016 原文链接:https://antonioleiva.com/kotlin-integrations-android-sdk/ 使用Ko ...
- ubuntu安装ANSYS17.2全过程
本次介绍在Ubuntu kylin1604下安装Ansys 17.2的全部过程. 1 安装文件准备 关于ANSYS的软件安装文件,在网络上可以找到.这里采用SSQ版本的安装文件,如图所示,包含一个名为 ...
- github入门到上传本地项目【网上资源整合】
[在原文章的基础上,修改了描述的不够详细的地方,对内容进行了扩充,整合了网上的一些资料] [内容主要来自http://www.cnblogs.com/specter45/p/github.html#g ...