C#

C# プログラムでリソースを作って使う

投稿日:

プログラムで使うリソースには、文字列・画像などがあります。
こういったリソースは、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]ボタンを押したところ

 

 

-C#
-, , , , , ,

Copyright© プログラミングテクニック集キヤミー , 2020 All Rights Reserved.