tech fielders 2009/9/18 lt

39
「Silverlight 3 アプリの国際化の ハマりどころ ⼋⽊照朗 / terurou 株式会社コスモルート DSTokai / FLOSS桜⼭ / DeLLa.JS / Python東海

Upload: terurou

Post on 28-May-2015

2.270 views

Category:

Technology


0 download

DESCRIPTION

「Silverlight 3 アプリの国際化」のハマりどころ

TRANSCRIPT

Page 1: Tech Fielders 2009/9/18 LT

「Silverlight 3 アプリの国際化のハマりどころ

⼋⽊照朗 / terurou株式会社コスモルート

DSTokai / FLOSS桜⼭ / DeLLa.JS / Python東海

Page 2: Tech Fielders 2009/9/18 LT

1

⾃⼰紹介

Page 3: Tech Fielders 2009/9/18 LT

2

⾃⼰紹介

• 株式会社コスモルート(名古屋の会社)に勤務– Enterprise RIA エンジニア(JavaScript、Silverlight)

– いちおう研究開発要員(WEB技術全般)

– たまにプロジェクトマネージャも

– 現在は Silverlight 3 開発案件のため、東京に常駐中

• 昨⽇から急にインフラ要員になりましたけどね…!

• DSTokai(東海地⽅のメタコミュニティ)管理⼈

Page 4: Tech Fielders 2009/9/18 LT

3

⾃⼰紹介

⽐較的最近の活動

• Tech Fielders インタビュー #23– IronPython は、⽤途によって凄く便利な道具になる

http://www.microsoft.com/japan/powerpro/TF/interview/23_1.mspx

– 他の⽅と⽐較すると、明らかに⼀⼈だけ浮いている…

• PHP 逆引きレシピ(翔泳社)を執筆– PHP本の中では⼀番売れてるらしいです

Page 5: Tech Fielders 2009/9/18 LT

4

さて、本題。

Page 6: Tech Fielders 2009/9/18 LT

5

さて、本題。

Silverlight 3 アプリケーションを国際化する際の基本的な⼿順とハマリどころをまとめてきました。

Page 7: Tech Fielders 2009/9/18 LT

6

さて、本題。

ライトニングトークのネタになる程度には⼿順がめんどくさくて、ハマります…。

Page 8: Tech Fielders 2009/9/18 LT

7

さて、本題。

ちなみに今⽇のスライド、調⼦に乗って作ってたら37枚になりました。たぶん時間⾜りません。

Page 9: Tech Fielders 2009/9/18 LT

8

国際化の⼿順

Page 10: Tech Fielders 2009/9/18 LT

9

国際化の⼿順

1.プロジェクトファイルに対応する⾔語(カルチャ)を記述

2.アセンブリリソースファイル(.resx)を作成3.XAMLにリソース埋め込む4.【実⾏時】表⽰する⾔語(カルチャ)を指定

※基本的にはMSDNの⼿順の変形です。 Silverlight ベースのアプリケーションのローカライズ http://msdn.microsoft.com/ja-jp/library/cc838238%28VS.95%29.aspx

Page 11: Tech Fielders 2009/9/18 LT

10

国際化の⼿順

⽇本語(ja-JP)と英語(en-US)に対応させる例をベースに解説していきます。

Page 12: Tech Fielders 2009/9/18 LT

11

国際化の⼿順

1.プロジェクトファイルに対応する⾔語(カルチャ)を記述

プロジェクトファイル(.csproj, .vbproj)をお好みのテキストエディタで開いて、<SupportedCultures> に対応させたいカルチャ名を記述します。

Visual Studio 単独では設定不可能!

Page 13: Tech Fielders 2009/9/18 LT

12

国際化の⼿順

<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProductVersion>9.0.30729</ProductVersion> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{87702BBC-F726-481B-AE35-18F56F6EEF4D}</ProjectGuid> <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> <OutputType>Library</OutputType> <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>i18n</RootNamespace> <AssemblyName>i18n</AssemblyName> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <SilverlightApplication>true</SilverlightApplication> <SupportedCultures>ja-JP;en-US</SupportedCultures> <XapOutputs>true</XapOutputs> <GenerateSilverlightManifest>true</GenerateSilverlightManifest> <XapFilename>i18n.xap</XapFilename> <SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate> <SilverlightAppEntry>i18n.App</SilverlightAppEntry> <TestPageFileName>TestPage.html</TestPageFileName> <CreateTestPage>true</CreateTestPage> <ValidateXaml>true</ValidateXaml>

・・・

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

セミコロンで区切ると複数カルチャを指定できます。

Page 14: Tech Fielders 2009/9/18 LT

13

国際化の⼿順

2.アセンブリリソースファイル(.resx)を作成

ソリューションエクスプローラの右クリックメニューから [追加] → [新しい項⽬] を選択し、

[アセンブリリソースファイル]を選択します。

Page 15: Tech Fielders 2009/9/18 LT

14

国際化の⼿順

⽇本語(ja-JP)、英語(en-US)に対応する場合は以下のように3つのリソースファイルを作成します。

• Resource.resx(インバリアントカルチャ⽤)• Resource.ja-JP.resx• Resource.en-US.resx

※インバリアントカルチャとは特定の⾔語/地域に 依存していないカルチャのことです。

Page 16: Tech Fielders 2009/9/18 LT

15

国際化の⼿順

Resouce.resx を開いて、アクセス修飾⼦ をPublic に変更します。(初期値は Internal )

Resouce.ja-JP.resx、Resouce.en-US.resx はコード⽣成なし のままにしておきます。

Page 17: Tech Fielders 2009/9/18 LT

16

国際化の⼿順

3つのリソースファイルに置き換え⽂字列を同じ名前で追加します。

Resource.resx Resource.ja-JP.resx Resource.en-US.resx

Page 18: Tech Fielders 2009/9/18 LT

17

国際化の⼿順

3.XAMLにリソース埋め込む

App.xaml の <App.Resouces> にリソースを埋め込んで、Bindingするだけなのですが…。

アセンブリリソースファイルの⾃動⽣成コードはなぜかコンストラクタが internal なので、そのままでは XAML に埋め込めません…。これはバグなのか仕様なのか…。

Page 19: Tech Fielders 2009/9/18 LT

18

国際化の⼿順

• ⾃動⽣成コードのコンストラクタを public にする– リソースを変更する度にアクセス修飾⼦が internal に

戻されてしまう…。

• リソースをプロパティとするクラスを作る– MSDN の⼿順ではこちらの⼿順を紹介

– Binding の際のパス⽂字列が⻑くなる…。

解決するには以下のどちらかを⾏います。

Page 20: Tech Fielders 2009/9/18 LT

19

国際化の⼿順

リソースをプロパティとするクラスを作る場合は、

こんな感じに定義します。

public class LocalizedResouce{ public LocalizedResouce() { }

private static Resource resource = new Resource();

public Resource Resource { get { return resource; } }}

Page 21: Tech Fielders 2009/9/18 LT

20

国際化の⼿順

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:resources="clr-namespace:i18n" x:Class="i18n.App"> <Application.Resources> <resources:Resource x:Key="Resource" /> </Application.Resources></Application>

あとは App.xaml にリソースを埋め込み、

⾃動⽣成コードを public にした場合 <resources:Resource x:Key="Resource" />

クラスを作った場合 <resources:Resource x:Key="LocalizedResource" />

Page 22: Tech Fielders 2009/9/18 LT

21

国際化の⼿順

<TextBlock Text="{Binding NameLabel, Source={StaticResource Resouce}}" />

置き換え箇所で Binding していきます。

<TextBlock Text="{Binding Resource.NameLabel, Source={StaticResource LocalizedResouce}}" />

⾃動⽣成コードを public にした場合

クラスを作った場合

Page 23: Tech Fielders 2009/9/18 LT

22

国際化の⼿順

CJK(中国語、⽇本語、韓国語)対応

<UserControl Language="ja-JP" />

CJKを適切に表⽰するためには更に設定が必要です。

ルート要素で以下のように指定します。

Page 24: Tech Fielders 2009/9/18 LT

23

国際化の⼿順

4.【実⾏時】表⽰する⾔語(カルチャ)を指定

2つの指定⽅法があります。

• HTMLの<object>要素内で指定

• プログラム中で指定

Page 25: Tech Fielders 2009/9/18 LT

24

国際化の⼿順

HTMLの<object>要素内でカルチャを指定

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"

width="100%" height="100%">

<param name="source" value="Sample.xap"/>

<param name="onError" value="onSilverlightError" />

<param name="background" value="white" />

<param name="minRuntimeVersion" value="3.0.40624.0" />

<param name="autoUpgrade" value="true" />

<param name="culture" value="ja-JP" />

<param name="uiculture" value="ja-JP" />

<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0"

style="text-decoration:none">

<img src="http://go.microsoft.com/fwlink/?LinkId=108181"

alt="Microsoft Silverlight を入手" style="border-style:none"/>

</a>

</object>

<param name="culture" value="ja-JP" /><param name="uiculture" value="ja-JP" />

Page 26: Tech Fielders 2009/9/18 LT

25

国際化の⼿順

プログラム中でカルチャを指定

private void Application_Startup(object sender, StartupEventArgs e)

{

Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP");

Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP");

this.RootVisual = new MainPage();

}

Thread.CurrentThread.CurrentCulture

= new CultureInfo("ja-JP");

Thread.CurrentThread.CurrentUICulture

= new CultureInfo("ja-JP");

Page 27: Tech Fielders 2009/9/18 LT

26

国際化の⼿順

以上で基本的な⼿順は完了です。

⾮常に簡単でしたね!

Page 28: Tech Fielders 2009/9/18 LT

27

補⾜(注意するポイント)

Page 29: Tech Fielders 2009/9/18 LT

28

補⾜(注意するポイント)

XP と Vista/7 ではデフォルトカルチャの

解決ルールが異なるため、環境によって挙動が

変わってしまう場合があります。

カルチャは明⽰的に初期値を指定しましょう。

1.カルチャ指定時の注意点

Page 30: Tech Fielders 2009/9/18 LT

29

追記(2009/09/30) この部分の記載内容は誤りです。

補⾜(注意するポイント)

カルチャを何も指定せずにアプリを実⾏。

• XP → インバリアントカルチャ

• Vista/7 → OSのカルチャ設定に依存?     ⽇本語版では ja-JP になった。

実際に遭遇したケース

Page 31: Tech Fielders 2009/9/18 LT

30

追記(2009/09/30) この部分の記載内容は誤りです。

補⾜(注意するポイント)

また、ja-JP と en-US しか⽤意していないのに

fr-FR などを指定した場合も同じ挙動に…。

Page 32: Tech Fielders 2009/9/18 LT

31

追記(2009/09/30)

補⾜(注意するポイント)

アセンブリリソースを⽤意していない

カルチャを表⽰⾔語として指定した場合、

読み込まれるカルチャが環境によって

異なる。(OSに依存している…?)

実際に遭遇したケース

Page 33: Tech Fielders 2009/9/18 LT

32

追記(2009/09/30)

補⾜(注意するポイント)

Resource.rexs と Resource.ja-JP.resx の

2つを⽤意し、en-US を指定した場合

• XP → インバリアントカルチャ

• Vista/7 → ⽇本語版OSでは ja-JP

Page 34: Tech Fielders 2009/9/18 LT

33

補⾜(注意するポイント)

普通に Binding すると、こういう⾔語切り替えUIは実装できない。

2.アセンブリリソースファイルの⾃動⽣成コードはINotifyPropertyChanged、DependencyPropertyではない。

Page 35: Tech Fielders 2009/9/18 LT

34

補⾜(注意するポイント)

• Binding しない。プログラムで代⼊する。NameLabelTextBlock.Text = Resource.NameLabel.toString();

• ⾃動⽣成コードをラッッピングする。カルチャを切り替えたタイミングで INotifyPropertyChanged, DependencyProperty が動作するように。

解決策

Page 36: Tech Fielders 2009/9/18 LT

35

補⾜(注意するポイント)

ちなみに私は全部 Binding に切り替えた後で、

気がついちゃったので、⾃動⽣成コードから

INotifyPropertyChanged な動的クラスを⽣成する

ジェネレータを作ることで解決しました。

Page 37: Tech Fielders 2009/9/18 LT

36

まとめ

Page 38: Tech Fielders 2009/9/18 LT

37

まとめ

開発者が意識することが多すぎです。

マイクロソフトさんには是⾮改善して頂きたい。

※これを⾔うために国際化なんて地味なネタでライトニングトークに

 申し込んだとか、そうでないとか。

Page 39: Tech Fielders 2009/9/18 LT

38

ご清聴ありがとうございました