プログラムで使うリソースには、文字列・画像などがあります。
こういったリソースは、Visual Studioなどの開発環境下であれば簡単に作り使うことができます。
ここでは、あえてプログラムでリソースファイル(.resx)を作成させてそのリソースファイルからリソースを取得して使ってみます。
リソースファイル(.resx)を作る
プログラムでリソースファイルを作るには、System.Resources.ResXResourceWriterクラスを使います。
ただ、このクラスを使うには参照設定に”System.Windows.Forms”が入っている必要があります。
リソースの追加は、生成したSystem.Resources.ResXResourceWriterクラスオブジェクトのAddResourceメソッドで「名前」「値」(文字列リソースの場合文字列)を渡します。
AddResourceメソッドの「値」は文字列だけでなくobjectクラスも渡せます(画像の場合はBitmapオブジェクトなど)。
また、resxファイルはUTF-8のXMLファイルなので、簡単な文ですが3か国語のリソースファイルを作ってみます。
// // リソース出力先のファイルパス string filepath = System.IO.Path.Combine(Application.StartupPath, "MyResources.resx"); // ResXResourceWriterを作成 System.Resources.ResXResourceWriter writer = new System.Resources.ResXResourceWriter(filepath); // 文字列のリソースを追加する writer.AddResource("Hello_en-us", "Good morning. How are you?"); writer.AddResource("Hello_ja", "おはよう、元気ですか?"); writer.AddResource("Hello_zh-cn", "早上好,你怎么样?"); // ファイルに書き込んで、閉じる writer.Close();
このコードで作成したリソースファイル(.resx)の中身はこんな感じです。
<?xml version="1.0" encoding="utf-8"?> <root> <!-- Microsoft ResX Schema Version 2.0 The primary goals of this format is to allow a simple XML format that is mostly human readable. The generation and parsing of the various data types are done through the TypeConverter classes associated with the data types. Example: ... ado.net/XML headers & schema ... <resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="version">2.0</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <value>[base64 mime encoded serialized .NET Framework object]</value> </data> <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <comment>This is a comment</comment> </data> There are any number of "resheader" rows that contain simple name/value pairs. Each data row contains a name, and value. The row also contains a type or mimetype. Type corresponds to a .NET class that support text/value conversion through the TypeConverter architecture. Classes that don't support this are serialized and stored with the mimetype set. The mimetype is used for serialized objects, and tells the ResXResourceReader how to depersist the object. This is currently not extensible. For a given mimetype the value must be set accordingly: Note - application/x-microsoft.net.object.binary.base64 is the format that the ResXResourceWriter will generate, however the reader can read any of the formats listed below. mimetype: application/x-microsoft.net.object.binary.base64 value : The object must be serialized with : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.soap.base64 value : The object must be serialized with : System.Runtime.Serialization.Formatters.Soap.SoapFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.bytearray.base64 value : The object must be serialized into a byte array : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:element name="root" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="metadata"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" /> </xsd:sequence> <xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="assembly"> <xsd:complexType> <xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="data"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="resheader"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" /> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <resheader name="resmimetype"> <value>text/microsoft-resx</value> </resheader> <resheader name="version"> <value>2.0</value> </resheader> <resheader name="reader"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <data name="Hello_en-us" xml:space="preserve"> <value>Good morning. How are you?</value> </data> <data name="Hello_ja" xml:space="preserve"> <value>おはよう、元気ですか?</value> </data> <data name="Hello_zh-cn" xml:space="preserve"> <value>早上好,你怎么样?</value> </data> </root>
ファイルの前半部分(というよりほとんど?)はコメントです。
resxファイルの最後のほうにプログラムから出力したリソースの情報があります。
リソースファイル(.resx)からリソースを取得する
先ほどのプログラムで生成したリソースファイル”MyResources.resx”からリソースを取得して画面に表示するプログラムを作成します。
せっかくなので、簡単な言語切替っぽいプログラムにしてみます。
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // comboBox1.Items.Clear(); comboBox1.Items.Add("English"); comboBox1.Items.Add("日本語"); comboBox1.Items.Add("中文"); } private void btnExit_Click(object sender, EventArgs e) { // this.Close(); } private void btnChange_Click(object sender, EventArgs e) { // // 読み込む.resxファイルのパス string resxFile = System.IO.Path.Combine(Application.StartupPath, "MyResources.resx"); //ResXResourceSetを作成する System.Resources.ResXResourceSet resx = new System.Resources.ResXResourceSet(resxFile); // リソース名"Hello_**"の文字列リソースを取得する // "Hello_en-us" ... 英語 // "Hello_ja" ... 日本語 // "Hello_zh-cn" ... 中国語 string key = ""; switch (comboBox1.SelectedIndex) { case 1: // "日本語"を選んだ場合 key = string.Format("Hello_{0}", "ja"); break; case 2: // "中文"を選んだ場合 key = string.Format("Hello_{0}", "zh-cn"); break; case 0: // "English"を選んだ場合 default: key = string.Format("Hello_{0}", "en-us"); break; } string message = resx.GetString(key); lblTitle.Text = message; //閉じる resx.Close(); } }
先ほど生成したファイル”MyResources.resx”は、実行ファイル(.exe)が出力されるフォルダに用意しておきます。
実行した結果
起動直後
ドロップダウンで”English”を選んで[Change]ボタンを押したところ
ドロップダウンで”日本語”を選んで[Change]ボタンを押したところ
ドロップダウンで”中文”を選んで[Change]ボタンを押したところ