当前位置: 首页 > 编程日记 > 正文

解析大型.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
BEGINSET NOCOUNT ON;
SET @KeyText = UPPER(@KeyText)
DELETE LanguageTranslation WHERE KEYTEXT = @KeyTextINSERT 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')ENDGO

为了简化简体到繁体的转化,调用.NET  VB类库中的方法,实现简体转化为繁体的功能,简体转化为繁体:

public string ConvertToTraditionalChinese(string label)
{return Strings.StrConv(label, VbStrConv.TraditionalChinese, 0);
}

基本上满足需求,转换的准确率不如Word或一些在线翻译工具。

将存储过程和语言转换的方法封装起来,做成一工具,输入要翻译的资源字符串和简体翻译,生成存储过程调用。

image

程序启动时,设计一个翻译资源缓存字典表,分别存放对应语言的键值对。

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提供的解决方案,地址是

http://stackoverflow.com/questions/373388/best-way-to-implement-multi-language-globalization-in-large-net-project

http://stackoverflow.com/questions/119568/best-practice-to-make-a-multi-language-application-in-c-winforms

这篇问答中提到几个工具,这几个工具的网站都可以打开,读者若是在寻找多国语言方案,可实际操作体会一下。

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/

相关文章:

服务器架设笔记——Apache模块开发基础知识

通过上节的例子&#xff0c;我们发现Apache插件开发的一个门槛便是学习它自成体系的一套API。虽然Apache的官网上有对这些API的详细介绍&#xff0c;但是空拿着一些零散的说明书&#xff0c;是很难快速建立起一套可以运行的系统。&#xff08;转载请指明出于breaksoftware的csd…

解密Elasticsearch技术,腾讯开源的万亿级分布式搜索分析引擎

「免费学习 60 节公开课&#xff1a;投票页面&#xff0c;点击讲师头像」作者 | johngqjiang&#xff0c;腾讯 TEG 云架构平台部研发工程师来源 | 腾讯技术工程&#xff08;ID&#xff1a;Tencent_TEG&#xff09;【导读】Elasticsearch&#xff08;ES&#xff09;作为开源首选…

Centos5上firefox的升级

Centos5上firefox的升级默认Centos5上firefox的版本是1.5当我们使用yum update firefox提示到的版本还是1.5 可是我们在使用1.5版本的firefox可能会有一些问题&#xff0c;比如打不开QQ空间接下来我们就将系统的firefox从rpm包的1.5版本升级到tar包的3.0首先删除1.5版本的fire…

cheat engine lua

function CEButton1Click(sender) local x getProperty(CETrainer.CEEdit1,"Text")--这句很重要,获取文本框的值 --writeInteger(0x42c0c0,readInteger(0x42c0c0)x)--设置0X42C0C0地址的值 setProperty(CETrainer.CEEdit2,"Text","0001000")--设…

服务器架设笔记——使用Apache插件解析简单请求

一般来说&#xff0c;对于一个请求&#xff0c;服务器都会对其进行解析&#xff0c;以确定请求的合法性以及行进的路径。于是本节将讲解如何获取请求的数据。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; 我们使用《服务器架设笔记——编译Apache及其插件》…

如何用Python快速抓取Google搜索?

「免费学习 60 节公开课&#xff1a;投票页面&#xff0c;点击讲师头像」作者 | linksc译者 | 弯月&#xff0c;编辑 | 郭芮来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;自从2011年 Google Web Search API 被弃用以来&#xff0c;我一直在寻找其他的方法来抓取G…

利用歌词插件 让WMP活起来

如果利用起这个歌词插件的话 是不是可以减少下载那么多播放器和每次更新的烦恼呢?因为WMP是系统自带的.可以下载的插件名称:Wa3 Music Engine 或者乐辞的歌词秀插件转载于:https://blog.51cto.com/david25/84211

Linux性能研究(总)

http://www.vpsee.com/2009/11/linux-system-performance-monitoring-introduction/ http://www.jb51.net/LINUXjishu/34607.html 公司有个测试服务器&#xff0c;上面跑了几个应用和一个DB。 DB被这个几个应用使用。 最近老是被挂掉。 CPU 使用率100%。 搞到最后大家都不能用。…

万字干货:如何从零开始构建企业级推荐系统?

「免费学习 60 节公开课&#xff1a;投票页面&#xff0c;点击讲师头像」作者丨gongyouliu编辑丨zandy来源 | 大数据与人工智能&#xff08;ID: ai-big-data&#xff09;最近几个月有很多人咨询作者怎么从零开始搭建工业级推荐系统&#xff0c;有做音视频的、有做新闻资讯的、有…

Mocha BSM基础架构管理——灵活的网络拓扑展现

业务需求与挑战企业的网络拓扑结构与设备时常变化&#xff0c;人工往往难以维护网络拓扑。尤其对于上千台设备的大型网络来说情况更为复杂。当用户网络设备大量增加后&#xff0c;网络结构异常复杂&#xff0c;用户的网络拓扑很难在一个屏幕上展现或者很难找到要查阅的网络拓扑…

服务器架设笔记——打通MySQL和Apache

在《服务器架设笔记——使用Apache插件解析简单请求》一文中&#xff0c;我们已经可以获取请求内容。这只是万里长征的第一步。因为一般来说&#xff0c;客户端向服务器发起请求&#xff0c;服务器会有着复杂的业务处理逻辑。举个例子&#xff0c;大部分客户端软件都有日志模块…

【Maven】maven的安装配置和ecplise结合

2. Maven的安装和配置 2.1. 安装 进入Maven官网的下载页面&#xff1a;http://maven.apache.org/download.cgi&#xff0c;如下图所示&#xff1a; 选择当前最新版本&#xff1a;“apache-maven-3.0.4-bin.zip”&#xff0c;下载到本地&#xff0c;解压缩到本地磁盘D:下。 2…

2020年趋势一览:AutoML、联邦学习、云寡头时代的终结

作者 | Roberto Sannazzaro&#xff0c;Ben Longstaff译者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 【导读】在 2020 年来临之际&#xff0c;新年前夕往往是人们回顾过去一年并展望来年的好时机。本文将深入探讨了关于 AI 的技术和非技术方面的趋势&am…

使用C++实现一套简单的状态机模型——实例

一般来说&#xff0c;“状态机”是一种表达状态转换变换逻辑的方法。曾经有人和我讨论过为什么不直接用ifelse&#xff0c;而要使用“状态机”去实现一些逻辑&#xff0c;认为使用“状态机”是一种炫技的表现。然而对于大型复杂逻辑的变化和跳转&#xff0c;使用ifelse将带来代…

net通过oledb 和ibm自带连接方式,连接db2数据库出错

第一种通过ibm方式连接 DataSet ds new DataSet(); OleDbConnection cn new OleDbConnection( "ProviderIBMDA400.1;Data Source192.168.21.10;User IDb4dd;" "Passwordb4dd;Default CollectionQIBMPP"); …

SAP QM 'QM System' 有什么控制作用?

SAP QM ‘QM System’ 有什么控制作用&#xff1f; QM system可以控制如下二点&#xff1a; 1>如果我方与Vendor的质量标准匹配&#xff0c;且相互认证&#xff0c;那么我方收货后不用检验&#xff0c;系统不产生检验批&#xff1b;如果我方与vendor的质量标准匹配&#x…

使用C++实现一套简单的状态机模型——原理解析

在上一文中&#xff0c;我们介绍了该状态机模型的使用方法。通过例子&#xff0c;我们发现可以使用该模型快速构建满足基本业务需求的状态机。本文我们将解析该模型的基础代码&#xff0c;以便大家可以根据自己状态机特点进行修改。&#xff08;转载请指明出于breaksoftware的c…

干货:NIST评测(SRE19)获胜团队声纹识别技术分析 | CSDN博文精选

作者 | xjdier来源 | CSDN博文精选(*点击阅读原文&#xff0c;查看作者更多精彩文章&#xff09;近日&#xff0c;NIST说话人识别技术评测 (Speaker Recognition Evaluation&#xff0c;SRE&#xff09;正式公布榜单&#xff0c;芯片初创公司清微智能和清华大学等机构组成的联队…

网络系统传输负载测试

网络系统传输负载测试 随着企业各种信息系统相继投入使用&#xff0c;生产、管理信息逐步增加&#xff0c;企业网络规模迅速扩大&#xff0c;信息城域网承受着空前的压力&#xff0c;网络带宽严重不足&#xff0c;网络系统传输丢包、设备死机情况频频发生。我们需要对网络状况做…

android圆形旋转菜单,而对于移动转换功能支持

LZ该公司最近接手一个项目&#xff0c;需要写一个圆形旋转菜单&#xff0c;和菜单之间的移动换位支持&#xff0c;我本来以为这样的demo如若互联网是非常。想想你妈妈也帮不了我&#xff0c;空旋转&#xff0c;但它不能改变位置&#xff0c;所以LZ我们只能靠自己摸索。 最后LZ参…

微信9年:张小龙指明方向,微信AI全面开放NLP能力

作者 | 夕颜责编 | 王金许出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;一年一度的微信公开课 Pro 在广州保利世贸博览馆如期举行。一大早&#xff0c;同在博览馆举办的广州年货促展会参会者&#xff0c;夹杂着参加腾讯公开课的与会者&#xff0c;让这里变得人流攒…

实现HTTP协议Get、Post和文件上传功能——使用WinHttp接口实现

在《使用WinHttp接口实现HTTP协议Get、Post和文件上传功能》一文中&#xff0c;我已经比较详细地讲解了如何使用WinHttp接口实现各种协议。在最近的代码梳理中&#xff0c;我觉得Post和文件上传模块可以得到简化&#xff0c;于是几乎重写了这两个功能的代码。因为Get、Post和文…

第一篇文章,做个纪念

第一篇文章,做个纪念,这个blog好吗?拭目以待!转载于:https://blog.51cto.com/197536/88241

Maven工程引入jar包(转)

Maven项目引入jar包的方法&#xff0c;希望能帮助有需要的朋友们 法一.手动导入&#xff1a;项目右键—>Build Path—>Configure Build Path—>选中Libraries—>点击Add External Jars—>选中已事先下好的Jar包导入即可。 法二.通过pom.xml文件的Dependencies标…

实现HTTP协议Get、Post和文件上传功能——使用libcurl接口实现

之前我们已经详细介绍了WinHttp接口如何实现Http的相关功能。本文我将主要讲解如何使用libcurl库去实现相关功能。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; libcurl在http://curl.haxx.se/libcurl/有详细的介绍&#xff0c;有兴趣的朋友可以去读下。本文…

32岁程序员,补偿N+2:“谢谢裁我,让我翻倍!” 网友:榜样!

2019年的冬天&#xff0c;“冷”的有些频繁。12月19日&#xff0c;《马蜂窝被曝裁员40% UGC模式变现难&#xff1f;》爆火&#xff0c;据悉马蜂窝将裁员40%&#xff0c;交易中心成了“重灾区”&#xff0c;赔偿N2&#xff0c;留下的除搜索推荐、内容中心等核心部门外&#xff0…

山有木兮木有枝,心悦君兮君不知

《越人歌》今夕何夕兮&#xff0c;搴舟中流。 今日何日兮&#xff0c;得与王子同舟 蒙羞被好兮&#xff0c;不訾诟耻 心几烦而不绝兮&#xff0c;得知王子 山有木兮木有枝&#xff0c;心悦君兮君不知。本是《夜宴》中的&#xff0c;"山有木兮木有枝&#xff0c;心悦君兮君…

浅析电商、社区、游戏常用的 MySQL 架构

一般、或者必须是这样、MySQL 架构一定要结合业务来分析、设计、优化 所以不管是那种架构、根据业务要求组合成符合需求的即是最好的、不能泛泛而谈 同时、也必须注意数据的安全&#xff08;如ipsec,ssh&#xff0c;vpn传输&#xff09; 常见的架构都是进行业务切…

基于Co-Attention和Co-Excitation的少样本目标检测 | NeurIPS 2019

「免费学习 60 节公开课&#xff1a;投票页面&#xff0c;点击讲师头像」作者 | VincentLee来源 | 晓飞的算法工程笔记&#xff08;ID: gh_084c810bc839&#xff09;导读&#xff1a;论文提出CoAE少样本目标检测算法&#xff0c;该算法使用non-local block来提取目标图片与查询…

服务器架设笔记——搭建用户注册和验证功能

之前介绍的Apache Httpd相关内容&#xff0c;都是些零散的知识点。而实际运用中&#xff0c;我们要根据不同的业务&#xff0c;将这些知识点连接起来以形成各种组合&#xff0c;来满足我们的需求。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; 本文我将以用…