あいてぃーとふぼふ

実録☆WP7アプリケーション開発!(第3話)

ということで、前回はアイデアを2つにまで絞り込みました。今回はもう少しアイデアを煮詰めたうえで、どちらか一方のアイデアに絞り込みたいと思います。

あっち向いてホイ(仮)はどうですか?

とりあえず、アプリケーションの完成形をイメージするために、先行してイラストを描いてみました。う~ん…やはりというかなんというか。とりあえず、実現するとかなり気持ち悪い感じのアプリケーションになるであろうことは明らかですね(汗。作ってみるのも面白そうではありますが、プレイするにしても賢者モードの発動が必要不可欠となります。そもそも他人に紹介するのも勇気がいります。はじめてのアプリですので、やはり色々と宣伝はしたいですし…。うむむ…

メトロちゃん(仮)はどうですか?

やはり同様に、メトロちゃんを描いてアプリケーションのアイデアを煮詰めてみました。色々と考えてみましたが、基本的なストーリーはこうなりました。ロボットやリンゴが覇権を争うスマフォ業界において彗星のごとく現れたメトロちゃんが、WP7のシェアを拡大するために地球を一周してロボットやリンゴを一掃します。ただしこの際、敵を倒すためにはタイミングよく画面下のアプリケーションバーボタンを押す必要があります。つまり、俗にいう「リズムゲー」にするのが、比較的簡単に実現できそうで面白いかな~と思ったわけです。実装自体もSilverlightの機能を最大限に利用すれば、100行足らずのソースコードで実現できるかもしれません。

キミに決めた!

ということで、今回作成するアプリケーションは「メトロちゃん(仮)」に決定しました!「あっち向いてホイ(仮)」も非常に捨てがたいんですが、一発目のアプリがアレだと何だか人間性を疑われそうで怖いです。ということで、次回からは実装に入りつつ技術的な懸念事項や画面構成などを検討したいと思います。

実録☆WP7アプリケーション開発!(第2話)

今回は、作成するWP7アプリケーションのアイデアを考えてみたいと思います。ということで、実際にわたしが考えたアイデアを以下に公開しちゃいます!それにしても、やっぱりアイデアを出すのが一番大変だったりしますよね~。なんだかお疲れにゃんキャット

アイデアA:リーマン(仮)

このゲームでは、上司の絡み酒にしこたま付き合わされたサラリーマンが、押し寄せる吐き気をコントロールしつつ愛する家族の待つ我が家を目指すというゲームです。プレイヤーが操作するサラリーマンは、基本的に千鳥足のため常にふらふらしています。このため、加速度センサーの傾きでうまく制御しつつ、マンホールや通行人を避けて進みます。もしこれらに当たってしまうと、「SUSHIORI=STOCK(寿司折りストック)」…つまりライフが減少してしまいます。また、プレイ中は常に「GERO=GAGE(ゲロゲージ)」が上昇していくため、定期的に電信柱を見つけてゲージを解放してあげる必要があります。この際、ゲージのギリギリ具合によって「SOKAI-POINT(爽快ポイント)」が溜まる仕組みとなっており、このポイントによるランキング機能も実装することにしましょう。寿司折りがなくなるか、ゲロゲージが最大値をオーバーすると「GEeeM=OVER(ゲェームオーバー)」となります。他にも、ゲロゲージを一定時間溜めてフラッシュオーバーさせることにより発動可能な「GERO=SENSITIVE(ゲロの領域)」などの要素も考えてみました。ということで、個人的にはイチオシのアイデアです!…がいかんせん、全体的に下品すぎましたかね。でも結構気に入ったので時間があれば作ってみたいかも。

アイデアB:あっち向いてホイ(仮)

このゲームはとてもシンプルで、美少女と「ジャンケン」して「あっち向いてホイ」をするだけの内容です。西暦20xx年、ピュアな紳士たちの社交場では「あっち向いてホイ」が大流行~、みたいな時代背景です(謎。システムとしては、「ジャンケン」の入力にアプリケーションバーのボタンコントロールを利用したり、「あっち向いてホイ」の入力にToolkitのGestureServiceクラスなどを利用すれば、実装自体はそこまで難しくなさそうです。また肝心の美少女も、1枚絵と上下左右を向いた差分を用意すれば、これまた工数は抑えられそうです。ただし、バカ正直に作成すると単調なゲームになってしまいそうなので、リズミカルに入力しないと失敗するような要素を設けたりしたいところですね。また、何連勝できたかをランキングとして記録できるようにすれば、最低限のやりこみ要素も確保できそうです。でもこれ…実現したらかなり気持ち悪い感じのゲームになりそう…。

アイデアC:メトロちゃん(仮)

このゲームは、あえてユルい感じを演出することにより万人受けを狙います(言い切った)。でも正直いうと、あまり具体的な内容は決まっていません。だって1日で3つもアイデア出すとか無理ですよ…(汗。でも工数などを考慮すると、今回作成するアプリでは、ワンキーだけで遊べるような単純&爽快なゲームが一番ニーズに合っているのかもしれません。イラストに関しても、ユルいデフォルメキャラクターなら描くのも大した手間じゃありませんしね。

どれを採用する?

ということで、3つのアイデアを出してみたわけなんですが、このうちのどれを採用するか…それが問題ですね。あ、でも「リーマン」は除外しますよ!だってアプリケーションの審査で撥ねられそうな内容ですし、そもそも前回決めたコンセプトは「萌え系アプリ」だったわけで。…ってあれ?じゃあ、なんで「リーマン」なんて考えたんだろ…(´・ω・`;)

実録☆WP7アプリケーション開発!(第1話)

わたしもそろそろなにかしら、WindowsPhone7のアプリケーションを作って公開したいなぁ~。ということで!ここから数回にわたり、WP7アプリケーションの開発工程を記していきたいと思います。なおこの企画は、なんか突発的に思いついたのものですので、突然終了するかもしれないことをあらかじめお断りしておきます!(`・ω・´)ゞ

課題を決めよう!

今回は、あくまでマーケットプレイスにアプリケーションを公開することが最優先事項よ♪@みずほ先生。このため、あまり高度なアプリケーションは作成しません。…といいますか、高度なアプリを作るスキルがありません。また仕事や夏コミなどの都合上、あまり時間を割くこともできません。このため、できれば6月中に簡単なアプリをマーケットプレイスに公開するところまで漕ぎ着けたいところです。今回はこれを最重要な課題としましょう。

開発プラットフォームを決めよう!

WP7アプリケーションの開発に使用するプラットフォームは、UIアプリの開発に特化した「Silverlight」と、ゲームアプリの開発に特化した「XNA」のいずれかを選択することが可能です。「Silverlight」を利用する場合、XAMLと呼ばれるマークアップ言語とイベント駆動型のプログラミング手法により、比較的短かい期間でUIベースのアプリケーションを構築することが可能です。また「XNA」を利用する場合、低レベルかつ豊富なAPIを利用することができるため、自由度が高く高速なアプリケーションを構築することが可能です。前述のとおり今回は、開発にあまり時間を割くことができません。このため、開発効率の高いSilverlightを選択することにします。

コンセプトを決めよう!

とはいえ、単純なアプリケーションをただ作ってもあまり面白くないですよね。なので、WP7のアプリケーションを公開しているマーケットプレイスをすこし調べてみました。その結果、予想していた通り…いわゆる萌え系アプリはまだ少ないようです。このため、このあたりに付け入る隙(?)がありそうですね。ということで、コンセプトは萌え系アプリで行きましょう!でも萌え系というからには、どうしてもゲーム要素が強くなりそうです。限られた工数で実現するためには…どうしましょうか?そうですね!難しいことは明日考えましょう⊃_д_)⊃

WPDT7.1βの密かな改善点

最新のWP7アプリケーション開発環境である「WPDT7.1β」では、様々な新機能が追加されました。しかしながら、従来の機能に対する改善も色々と盛り込まれているようです。今日はその一部をご紹介しますね!

ターゲットの既定値がエミュレータに!

「VisualStudio 2010 Express for Windows Phone」を起動した際のターゲットの既定値が「Windows Phone Emulator」に変更されました。従来のWPDT7.0では、既定値が「Windows Phone Device」であったため、デバイスを接続していない時に実行エラーになるなど、なにかと煩わしかったものですが…。このあたりは地味にうれしい改善点ですね♪

アプリケーションアイコンに透明PNGが指定可能に!

アプリケーションアイコンの画像に透明PNGを利用することが可能になりました。透明PNGを利用した場合、透明部分にアクセントカラーが表示されます。これにより、WP7の標準アプリに利用されているアイコンと統一感を出すことができるようになりました。また従来のWPDT7.0では、アプリケーションアイコンをプロジェクトのルートディレクトリに配置しないとビルドエラーとなりましたが、WPDT7.1ではルートディレクトリ以外に移動させることが可能となりました。

画面遷移の履歴が消去可能に!

NavigationServiceクラスのRemoveBackEntryメソッドを利用して画面遷移の履歴を削除することが可能になりました。これにより、遷移履歴に残したくないような画面も気軽に利用することができます。なお、履歴が存在しない状態で本メソッドを実行した場合はInvalidOperationExceptionがスローされる…とMSDNには記載されていますが、実際には特に例外はスローされません。でも念のため、利用する際にはCanGoBackプロパティで履歴の存在有無を確認することを推奨します。

コマンドが利用可能に!

ボタンコントロールなどでコマンドが利用可能になりました。従来のWPDT7.0ではMvvmLightのButtonBaseExtensionsクラスなどを利用してコマンドをバインドさせる必要がありました。しかしながら、SL4ベースとなったWPDT7.1では、ボタンコントロールの標準機能としてコマンドが利用できるようになります。

Binding以外のクラスが依存関係プロパティとして利用可能に!

従来のWPDT7.0では、依存関係プロパティを作成する際にBindingクラス以外を使用するとXamlParseExceptionが発生しました。このため、PrismのBindingListenerクラスなどを利用してBindingクラスから無理くり何とかバインドソースを取得したりする必要がありました。しかしながら、最新のWPDT7.1βでは、Bindingクラス以外の一般的なクラスを依存関係プロパティで使用することが可能になります。これで依存関係プロパティがだいぶスッキリ記述できるようになりました。

他にも改善点は多々ありますが、続きはまた後日~。

WP7のゲームループはUIスレッド?(後編)

前回の検証結果(左記の画像)より、XNAのゲームループ(GameTimerクラスのイベントハンドラ)はUIスレッド上で動作することがわかりました。でも、これには大きな危険が潜んでいます。

UIスレッドの占有はダメ!

お気づきの方も多いと思いますが、この事実から読み取れる危険…、それはUIスレッドの占有には今まで以上に注意しなくてはならないということです。何を当たり前のことを…と思うかもしれませんが、ちょっと待ってください!たとえば、SilverlightのUIコントロールのイベントハンドラにおいて長時間処理を実行した場合、そのぶん、同様にUIスレッドを利用するGameTimerクラスのイベント発行が遅延してしまいます。このため、ゲームループのFPS(1秒間に処理する回数)が低下しますよね。この際に厄介なのは、OnUpdateイベントまでもがUIスレッドで動作するという事実です。これはつまり、UIスレッドの占有による弊害は、描画のコマ落ちなんて生易しいものではなく、ゲームの処理落ちに直結するということです。

XNAのみを利用する場合、処理に時間を喰ってしまった際は、意図的に描画処理をスキップして更新処理を優先させたりします。こうすることにより、描画のコマ落ちは発生しますが、ロジックの処理落ち(ボタンを押したのに認識されない等)を回避させることは可能です。ただしSilverlightと相互運用させる場合、こういう危険性を理解しないまま使用してしまうと後々厄介なことになりそうです。

まとめ!

後編に引っ張りましたけど、いいたいことはこれだけです。う~…ん、個人的にはOnUpdateイベントがUIスレッドである必要性が理解できません。Silverlightコントロールから値を取得するだけならば別段UIスレッドである必要はないわけですし…。でも、UpdateとDrawの実行順序を保証させたいがためだとすれば…なんとなく理解できるかも?いやでも…なんでかなー…。

ということで、全体的な完成度は少し残念な感じの「WPDT 7.1β」ではありますが、ことSilverlightとXNAの相互運用に関してはホント素晴らしいと思います。 SilverlightとXNAの共存なんて、まるで夢物語のようですね~♪いうなれば、仮面ライダーBLACKとシャドームーンが共闘するくらいアツイ 展開!…かな?かな?

WP7のゲームループはUIスレッド?(前編)

「WPDT 7.1β」では、SilverlightとXNAを相互運用することが可能となりました。この機能を利用することにより、例えばSilverlightのコントロールとXNAのゲームロジックを同一の画面内で共存させることが可能となります。個人的にイチ押しの機能です。

ちなみにこの機能は、Silverlight5のDrawingSurfaceクラスにおいて、より洗練された形で実装されています。ですがそれでも、利用する際にはXNAに関する知識が少なからず必要となります。また、WP7も将来的にはSilverlight5ベースになるでしょうし、今のうちからXNAの使い方を理解しておくのも良いと思います。

話が少しそれましたが、左記画像のアプリではこの機能を利用して、UIコントロールをSilverlightで制御し、ローザさんの3DモデルをXNAで制御しています。メッシュデータの利用方法など、XNAの基礎知識に関してはまた別の機会にご紹介するとして、今日の本題はXNAのゲームループからSilverlightのUIコントロールを操作することは可能か?という内容です。たとえば、3Dモデルのアニメーションが終わったらUIコントロールの状態を変更する、みたいなことが可能かどうかということですね。

まずはおさらい!

SilverlightとXNAを相互運用する場合、WP7.1ではGameTimerクラスを利用します。早い話、このタイマーがOnUpdateイベントとOnDrawイベントを交互に発行…つまりゲームループを発生してくれるので、これらのイベント内でXNAの更新処理と描画処理をしてあげればよいわけです。概略は右記画像のとおりです。仕組みは単純ですね~!このため、当然ではありますが、SilverlightのUIコントロールをXNAのゲームループから参照しても、別にビルドエラーにはなりません。でもじゃあ実行時に、XNAのゲームループ内からSilverlightのUIコントロールを操作した場合は…一体どうなるのでしょう?

やってみよう!

ということで、やってみました!結論から先に申しますと、XNAのゲームループからSilverlightのUIコントロールを操作することは可能です!やったね、たえちゃん!…ん?でも待てよ。たしかSilverlightのUIコントロールはUIスレッド以外から操作することはできないはず…。なのにうまく動くのは…なぜ?

調べてみよう!

これを検証するために、左記のようなコードにおいて、SilverlightのイベントハンドラとXNAのゲームループのスレッドIDを取得し比較してみました。すると面白いことに、上記のスレッドIDは完全に一致します。このことから、XNAのゲームループはUIスレッド上で実行されていることがお分かりいただけると思います。GameTimerクラスは、普通のTimerというよりはむしろDispatcherTimerに近い感じなんですね。ともあれこれで、XNAのゲームループ内からSilverlightコントロールをガンガン更新しても何ら問題ないことがわかりました。実際に、最大FPSで回しているゲームループからテキストボックスのテキストを(1秒間に数十回)変更しても、問題なく更新されます。

潜む危険…

…でも、この事実に喜んでばかりもいられません。なぜなら、この事実にはある重大な危険性が潜んでいるからです。ということで、続きは次回の投稿で!

WPDT 7.1 β リリース!

ということで、Mangoイベントも無事に終了です。イベント終了後に間もなく、日本語入力に対応した開発環境『Windows Phone Developer Tools 7.1 Beta』が公開されました!バージョンが7.1で…しかもβ?という謎仕様!このタイミングでそんな悠長にバージョン刻んで大丈夫なのか心配にはなりますが、なにはともあれ最新版のWPDT公開です!今日はその簡単なレビューをお届けします。

とその前に!当たり前のことではありますが、今回公開された最新の『WPDT7.1』はあくまでβ版です。このため、アプリケーションの開発には可能な限り従来のWPDTを利用することを強く推奨致します!これホント!

日本語入力に…対応!

WP7のエミュレータが日本語入力に対応しました!もちろんフリック入力も可能です。さらに「カーブフリック」と「確定フリック」をマスターすれば、すべての文字を1フリックで連続入力することが可能になります!これはスゴイ!ちなみに、日本語入力パネルから英語入力パネルを呼び出すことも可能なのですが、英語入力パネルから日本語をローマ字入力することはできないようです。せっかく呼び出せるんだから、これはできるようにしてほしいなぁ~。

日本語UIは…微妙@私的見解。

うまく言葉にできませんが…、個人的な日本語UIの第一印象はとにかく微妙!何が悪いって、たぶんUIのフォントだと思います。ただでさえ日本語は、英語と比べて文字数が多くなりがちなのに、このフォントではピボット等の次世代的なコントロールとミスマッチな気がしてなりません。もちろん、UIは未だ開発途中であるということは重々承知していますが…。せめてタイトルは太字にするとか、カーニングを調整するとか、いっそ明朝体にした方がよっぽどオシャレな気がします。でも一説によると、このフォントはWP7用に開発された素晴らしいフォントであるとのこと。えーと…マジですか。わたしにはもう国内で成功しているビジョンが見えないんですが…。でもでも、人の感性は千差万別ですものね。

SilverlightとXNAの相互運用は…最高!

SilverlightとXNAの橋渡しを実現するために、UIElementRendererというクラスが追加されました。簡単な話、要はこのUIElementRendererクラスを利用して、スプライトにSilverlightのUIパーツを描画し、XNAで描画したゲーム画面とセル画のように重ねることにより、SilverlightとXNAの共存を実現しています。また、従来のXNAと同様にコンテンツパイプラインも利用できるみたいです(ここはまだ未検証)。これでSilverlightエンジニアに対するゲーム開発の敷居がグッと低くなりそうですね!ちなみに、アプリケーションバーを不透明状態で利用するとコントロールの位置と入力座標がズレるので要注意です!個人的にはこの機能が「WPDT7.1」イチ押しかもです~!

BackgroundAgentは…期待通り!

この辺りは情報があふれているので割愛します。概ね予想通りのことができますね!…ていうか、タスク切り替えってどうやるの?戻るボタン長押しじゃないの?う~ん、わからない(汗

IE9は…使いづらい。

エミュレータ上ではIE9のパフォーマンスを実感することができませんので、ここではあくまで操作性のお話です。IE9では、アドレスバーが下に移った(アプリケーションバーに組み込まれた)ことにより、タイピングがしやすくなりました。でもこれにより、結果的にアプリケーションバーの「ボタン」と「メニュー」という統一されたUIデザインを自らブチ壊している気がしてなりません。現に、使用頻度の高いタブの切り替え機能がアプリケーションバーメニューに降格されてしまったため、タブ切り替えという機能を一目で認識できないですし、操作にかかる手間も1クリック増えてしまいました。慣れれば問題ないのかもしれませんが、慣れなきゃわからないUIなんてメトロなデザインじゃないのでわ…(汗?

タイルは…おもしろい!

WPDT7.1では、NotificationServiceを利用しなくてもタイルの更新が可能になりました!しかも、タイルを登録する際には画面のURL(パラメタ含む)を指定するようになっているので、アプリケーションのあらゆる画面(パラメタ含む)にリンクするタイルを登録することが可能です!さらに、登録したタイルは定期的に裏表を切り替えることもできるんです!これはおもしろいですね~!ちなみに、無限にパタパタするタイルを作ろうと思ってShellTileDataクラスの拡張を試みましたが無理でした。ちょっぴり残念。

データベースは…大歓迎!

これはホント、スゴク便利~!WPDT7.1では、そのものズバリなSqlClientクラスは存在していません。このため、従来のSQLをガリガリ記述するような感じではなく、DataContextを利用した、あくまで今風のデータベースアクセスが可能になってます!うーん、これは素晴らしい!

コマンド対応は…中途半端。

ボタンコントロールで普通にコマンドが使えることを確認しました!でも、相変わらずApplicationBarIconButtonはコマンドに対応していません(そもそもButtonBaseじゃないし)。あとMSDNにはUIElementのEffectが利用できるって書いてあるのに利用できない。…なんか中途半端?

エミュレータは…やばい。

エミュレータ上で動作させた場合、アプリケーションの起動が劇的に早くなりました!ただし、エミュレータ全体の動作としては何かもっさりした感じにグレードダウン。他にも、パノラマのスクロール時に画面が固まったり、IE9が稀にオート無限スクロール状態に陥ったり、DatePickerから日付を選択した際に画面がバグったり、…とにかくエミュレータのバグらしき現象が目立ちます。

特にひどいのは、既存のアプリケーションの挙動がいろいろと変わってしまうこと。例えば、パノラマ内に水平スクロール可能なリストボックスを配置したアプリケーションにおいて、リストボックスを水平フリックした場合、従来のWPDTではきちんとパノラマが遷移してくれました。しかしWPDT7.1では、上記の場合にパノラマが遷移しなくなってしまいました。子のイベントが親に飛んで行かないイメージです。これがSilverlight4ベースになったことによる弊害なのか、それともエミュレータがまだβ版だからなのか、非常に判断に苦しみます…。なお、実機の挙動は従来のWPDTと同様です。

まとめ。

う~…ん、全体的にもう少し完成度の高いリリースを期待していたのですが…ちょっと残念かもです。期待を膨らませすぎたのか、テンション&モチベーションが降下気味…。しかも今回はβ版ということを確認せずにうっかりメインPCにインストールしてしまったのが痛かった!やはり現状のアプリケーション開発は従来のWPDTで行ったほうが無難だと思います…いやホント。とにかく、開発用に従来のWPDTを再構築しよう。

WP7の画面遷移時に指定するパスを短縮

WP7のSilverlightアプリでは、画面を遷移する際にUriを指定します。たとえば左記のような感じですね。でも、この際に指定するUriのパスは文字列なので、どうしてもリファクタリングに弱かったりします。また、異なるモジュールの画面に遷移する場合、モジュールの名称まで含めたパスを記述する必要があるため、パスが冗長になりがちです。そこで今回は、画面遷移時に指定するUriのパスを短縮する方法をご紹介します。

どうやって実現する?

正確には、パスを短縮するというよりは、パスを別の文字列にマッピングします。そして、画面遷移時にこのマッピング情報を利用し、指定した文字列に対応する画面に遷移できるようにします。これにより、例えば、”Page1″と指定するだけで”/View/Page1.xaml”画面に遷移できるようになります。

実装方法はどうするの?

パスと文字列をマッピングするためにはUriMapperクラスを利用します。このクラスのインスタンスをApp.xamlのリソースとして作成し、パスと文字列のマッピング情報を定義します。なおこの際、文字列はパターンマッチングな感じで記述できるのがミソです。その後、上記クラスのインスタンスをApp.xaml.csのルートフレームのUriMapperプロパティに設定します。なんと手順はたったのこれだけ!詳細は上記を参照してください。

使い方はどんな感じ?

NavigationServiceを利用して画面を遷移する際に、定義したマッピング情報に基づいて、文字列とパスのマッチング&変換が自動的に実施されます!具体例は左記のとおり。この方法を知っていると、いろいろと潰しが効くので便利ですよ~!(≧∀≦)ノ

サンプルプログラム!

サンプルプログラムはこちらからダウンロードすることが可能です。
UriMapperSample

WP7のバリデーション(改良編)

前回のサンプルプログラムでは、テキストを変更したタイミングでOKボタンの活性状態が変化しないことが問題でした。今回はこれを解決してみましょう。

なんでこうなるの?

この問題は、WP7ではない普通のSilverlightでも同様に起こります。なぜなら、Textプロパティにバインドしたソースの更新タイミングは LostFocusが既定値となっているためです。このタイミングは、Bindingクラスの『UpdateSourceTrigger』を利用することにより指定することが可能であり、既定値である『Default』値の振る舞いはコントロールごとに異なります。たとえばIsCheckedなどの依存関係プロパティでは、更新タイミングが『PropertyChanged』であるのに対し、Textプロパティだけは、パフォーマンスを考慮して更新タイミングが『LostFocus』となっているのです。この辺りの詳細はMSDNをご覧くださいね。

つまり、テキストが変更されるたびに検証処理を実施(OKボタンの活性状態を更新)するためには、TextプロパティのBindingのUpdateSourceTriggerをPropertyChangedに指定すれば解決できそうですね。以下のような感じです。さっそくやってみましょう!

でもね、できません(´・ω・`)!だってね、Silverlightで指定できるUpdateSourceTriggerの値はDefaultとExplicitだけなんです!って、なんじゃそらー!(`Д´)

ならどうするの?

ということで、毎度おなじみBehaviorを使用して解決しましょう!やるべきことはいたってシンプルで、テキストボックスのTextChangedイベントが発生したときに、Textプロパティのバインディングソースを更新します。これにより、UpdateSourceTriggerにPropertyChanged値を指定した場合と同様の効果を得ることができます。

Behaviorの実装方法とXAMLはこんな感じになります。なお、このBehaviorを利用した場合はバインディングソースがBehavior内で更新されるため、TextプロパティのUpdateSourceTriggerには『Explicit』を指定してあげると尚良しです。これで納得の挙動になりました!

サンプルプログラム!

改良版のサンプルプログラムは以下からダウンロードすることが可能です。
ValidationSample(v2)

WP7のバリデーション(基礎編)

バリデーションとは入力値の検証処理のことです。ところで、WP7におけるバリデーションってどうするのが正しいのでしょうか╹ω╹)?

標準の画面ではどうなってるの?

ちょっと調べた限りだと、WP7のBindingクラスにもValidatesOnExceptionsやNotifyOnValidationErrorプロパティは存在しています。しかし、DataAnnotationsの検証属性やIDataErrorInfo、INotifyDataErrorInfoといったクラスは存在していません。この時点で、従来のSilverlightのように赤いToolTipが表示されるようなことは期待できそうにありませんね…(´・ω・`)

なので、WP7のMS謹製な画面でバリデーションが必要そうな項目を探してみたところ、メールアドレスを入力するテキストボックスにおいて、必須項目やアドレスの形式を判定してました!で、結論から申しますと上記の画面では、入力値が正しくない場合に画面内の入力内容を確定するボタンが押せなくなる仕様となっていました。このため、ユーザさんが不意にアドレスの形式を誤ってしまったとしても、なぜボタンが押せないのかを即座に理解することができません。このシンプルさがメトロなのだといわれると…もうなにも言い返せませんよね~! (>ω<、)

実装するとこんな感じ!

ということで、WP7アプリでバリデーションを実施する場合、MVVMライクに行くならICommnadのCanExecuteメソッドで実施するのがよさそうですね。さっそく簡単なサンプルプログラムを作成してみました。このサンプルでは、テキストボックスに値が入力されていない場合にOKボタンが非活性状態となり、ついでにOKボタンを押下したときにメッセージボックスを表示する仕様とします。上段がView、下段がViewModelの実装例です。

ICommnadのCanExecuteメソッドを利用すると、コントロールのIsEnabledプロパティなどを明示的に設定していなくても、CanExecuteメソッドの戻り値に応じてコントロールの活性状態を自動的に変更してくれますので便利です。ほかにも、MvvmLightのButtonBaseExtensionsクラスやPrismのIInteractionRequestを利用することにより、上記の仕様を簡潔に実装してみました。

サンプルプログラム!

詳細な内容は以下のサンプルプログラムをご覧ください。
ValidationSample

ちょっとまって!

でも、実はこのサンプルプログラムにはちょっとした問題があります。実行してもらえればわかると思いますが、テキストボックスからロストフォーカスしたタイミングで検証が実行されるのです。つまり、テキストを変更してもそのタイミングでは検証処理が実行されない(ボタンの活性状態が変化しない)ため、テキストを空にしてもなんかOKボタンが押せそうな気になります(実際は押せませんが)。できれば1文字入力するごとにOKボタンの活性状態を変化させたいですよね。ということで、これを解決する方法は次回の投稿でご紹介します!…でもやっぱり一筋縄じゃいきません(汗