かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Silverlightアプリケーションの国際化(DataAnnotations編)

Silverlightの国際化に関してはid:terurouさんの以下のスライドがとても参考になります!

Silverlight 3のころのお話なので、今は楽になってるのかな〜?と思ったらそんなことありませんでした。

本題

SilverlightアプリケーションでDataAnnotations使えばプロパティにDisplayAttribute使ってDataGridのヘッダーに表示する文字列とかを指定することが出来ますね。

例えばこんな感じに。

namespace Silverlight.ResourceSample
{
    using System.ComponentModel.DataAnnotations;

    public class Person
    {
        [Display(Name="あいでぃ")]
        public int ID { get; set; }

        [Display(Name = "おなまえ")]
        public string Name { get; set; }
    }
}

そしてMainPage.xamlにDataGridを置きます。

<UserControl 
    x:Class="Silverlight.ResourceSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" 
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

    <Grid x:Name="LayoutRoot" Background="White">
        <sdk:DataGrid Name="dataGrid1" />
    </Grid>
</UserControl>

そして、DataGridのItemsSourceに適当なデータを流し込みます。

namespace Silverlight.ResourceSample
{
    using System.Linq;
    using System.Windows.Controls;

    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            
            // DataGridに表示するデータを設定
            dataGrid1.ItemsSource = Enumerable.Range(1, 10)
                .Select(i => new Person 
                { 
                    ID = i, 
                    Name = "Tanaka Taro" + i 
                });
        }
    }
}

実行すると、こんな感じに表示されます。

この文字をロケールに応じて切り替えようというのが今回の目的です。やり方は簡単で、DisplayAttributeにあるResourceTypeプロパティを設定するとNameに指定された文字列を表示するのではなく、リソースキーとして認識してリソースから値をとってきてくれる仕組みになっているみたいです。

PersonResource.resxとPersonResource.ja-JP.resxとPersonResource.en-US.resxを以下のような感じに作ります。ポイントはPersonResource.resxをInternalからPublicにしてるところですね。

そして、PersonクラスのDisplayAttributeの指定を以下のようにします。

namespace Silverlight.ResourceSample
{
    using System.ComponentModel.DataAnnotations;

    public class Person
    {
        [Display(Name = "ID_Label", ResourceType = typeof(PersonResource))]
        public int ID { get; set; }

        [Display(Name = "Name_Label", ResourceType = typeof(PersonResource))]
        public string Name { get; set; }
    }
}

id:terurouさんのスライドでも語られてるように、Silverlightのプロジェクトファイルを開いて、手でサポートするロケールを指定します。

<SupportedCultures>ja-JP;en-US</SupportedCultures>

普通に実行すると、私は日本語OS使ってるので?ja-JPのリソースの文字列が表示されます。

英語を強制的に表示させるにはobjectタグのパラメータで指定します。(コード内からも指定はできます。やり方はid:terurouさんのスライド参照!)

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
	<param name="source" value="ClientBin/Silverlight.ResourceSample.xap"/>
	<param name="onError" value="onSilverlightError" />
	<param name="background" value="white" />
	<param name="minRuntimeVersion" value="4.0.50826.0" />
	<param name="autoUpgrade" value="true" />
    <!-- ここで指定 -->
	<param name="uiculture" value="en-US" />
    <param name="culture" value="en-US" />	
    <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration:none">
 		<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Microsoft Silverlight の取得" style="border-style:none"/>
	</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>

実行すると英語になってます。

ばっちりですね!!!ということでサンプルプロジェクトは以下からダウンロードできます。