人生是一场不能存盘的RPG,我只能尽量多搞几个Screenshot

February 28, 2007

String Resource使用

Filed under: .NET

1.方法1
把resource文件(Strings.resx和Strings.zh-CHS.resx)作为Embedded Resource build到Assembly中.
假定生成的assembly的default namespace为MyApp,resource位于Res 目录下,
则会在assembly中生成名为MyApp.Res.Strings.resources的resource,
同时生成zh-CHS目录,及:GMailClient.resources.dll,其中包含名为GMailClient.Res.Strings.zh-CHS.resources的资源.

//First parameter is: Assemlby default namespace + folder + base resource name
//Second parameter is : Assembly contails the
resourceManager = new ResourceManager(”MyApp.Res.Strings”, System.Reflection.Assembly.GetExecutingAssembly());
StringResources.GetString(resId);

测试:
使用 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(”zh-CN”);
设定UICulture,ResourceManager会使用这个Culture来读取对应的resource.

注意:Culture ‘zh-CHS’ is a neutral culture(与某种语言关联但不与国家/地区关联的区域性). It cannot be used in formatting and parsing and therefore cannot be set as the thread’s current culture.BUT, Culture ‘zh-CHS’ can be set as Current UI Culture.
在这里,我有意生成名为GMailClient.Res.Strings.zh-CHS.resources的resource(Chinese, neutral),但设定UICulture为zh-CN(PRC:Special),读取结果正确.可推测其逻辑为:对于一个Special Culture,找不到相应的
资源,就尝试其对应的neutral culture对应的资源.

对于NeutralCulture和:specified culture可以使用下面的函数进行转化
public static CultureInfo GetNeutralCulture(string cultureName)
{
System.Globalization.CultureInfo c = new System.Globalization.CultureInfo(cultureName);
if (! c.IsNeutralCulture)
{
c = new System.Globalization.CultureInfo(c.LCID & 0x3FF); //低10位
}
return c;
}
举例
zh-CHS 0x0004 Chinese (Simplified) , Neutral
zh-CN 0x0804 Chinese - China

zh-CHT 0x7C04 Chinese (Traditional) , Neutral
zh-TW 0x0404 Chinese - Taiwan
zh-HK 0x0C04 Chinese - Hong Kong SAR
zh-MO 0x1404 Chinese - Macao SAR
zh-SG 0x1004 Chinese - Singapore

下面的代码可以显示zh的相关的culture
foreach ( CultureInfo ci in CultureInfo.GetCultures( CultureTypes.AllCultures ) )
{
if ( ci.TwoLetterISOLanguageName == “zh” )
{
Console.Write( “{0,-6} {1,-40}”, ci.Name, ci.EnglishName );
if ( ci.IsNeutralCulture ) {
Console.WriteLine( “: neutral” );
}
else {
Console.WriteLine( “: specific” );
}
}
}
/*
This code produces the following output.

zh-CHS Chinese (Simplified) : neutral
zh-TW Chinese (Taiwan) : specific
zh-CN Chinese (People’s Republic of China) : specific
zh-HK Chinese (Hong Kong S.A.R.) : specific
zh-SG Chinese (Singapore) : specific
zh-MO Chinese (Macao S.A.R.) : specific
zh-CHT Chinese (Traditional) : neutral

*/

方法2:自己搞

public class PublicResourcesManager
{
private ResXResourceReader _resXReader;
private IDictionaryEnumerator _resXEnum;

public PublicResourcesManager(string resourceRootFolder, string resourceFileName)
{
CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentUICulture;
string resourceFolder = resourceRootFolder.TrimEnd(’\\’);
string fileName = String.Format(”{0}\\{1}\\{2}”, resourceFolder, ci.Name, resourceFileName);

try
{
// first try [country][region] folder…
_resXReader = new ResXResourceReader(fileName);
_resXEnum = _resXReader.GetEnumerator();
if (_resXEnum!=null)
return;
}
catch(Exception ex) {}

_resXReader.Close();

try
{
// try [country] folder (if culture isn’t a neutral culture…
if (!ci.IsNeutralCulture)
{
ci = new CultureInfo(ci.LCID & 0x03ff);

fileName = String.Format(”{0}\\{1}\\{2}”, resourceFolder, ci.Name, resourceFileName);
_resXReader = new ResXResourceReader(fileName);

_resXEnum = _resXReader.GetEnumerator();
if (_resXEnum!=null)
return;
}
}
catch(Exception ex) {}

_resXReader.Close();

try
{
// just try root folder…
fileName = String.Format(”{0}\\{1}”, resourceFolder, resourceFileName);
_resXReader = new ResXResourceReader(fileName);
_resXEnum = _resXReader.GetEnumerator();
}
catch(Exception ex)
{
string err = ex.Message;
}
}

public string GetString(string name)
{
string str = “”;

if (_resXEnum != null)
{
_resXEnum.Reset();
while (_resXEnum.MoveNext())
{
if (string.Compare(name, _resXEnum.Key.ToString(), true, CultureInfo.InvariantCulture)==0)
str=(string)_resXEnum.Value;
}
}
return str;
}
}

此处的逻辑是先找Folder\CultureName\Resource来找
如果失败,就把Culture转成neutral culture,再按Folder\CultureName\Resource找一次.
再失败,就尝试Folder\Resource

最常用的还是.net自己提供的resource管理机制,
在Form的property grid中可以设定form的Language,会为Form自动生成该Language的resource:
如MainForm.zh-CHS.resx,这些resource会被设置为Embedded Resource,其内容为:
<data name=”$this.Icon” type=”System.Drawing.Icon, System.Drawing”>
<value>…Binary Content…<value>
</date>
<data name=”$this.Text” type=”System.Drawing.Icon, System.Drawing”>
<value>Hello!<value>
</date>

在InitializeComponent()会生成代码
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));

resources.ApplyResources(this, “$this”);
resources.ApplyResources(this.pictureBox1, “pictureBox1″);

把resourc中的内容读出,并设置到from上.

3.使用时:
this.pictureBox1.Image = global::MyApplication.Properties.Resources.Winter;
不要轻易手动修改这些自动生成的代码,容易乱套.

Comments »

The URI to TrackBack this entry is: http://recordsome.blogsome.com/2007/02/28/p221/trackback/

No comments yet.

RSS feed for comments on this post.

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>



Anti-spam measure: please retype the above text into the box provided.






















Get free blog up and running in minutes with Blogsome
Theme designed by Hadley Wickham