かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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>

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

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