« [Metro] {プロジェクト名}_TemporaryKey.pfx が無い! | トップページ | Windows 8 RTM が MSDN で公開 ~ さぁ、 Metro アプリを作ろう! »

2012年6月11日 (月)

#cod2012jp 名古屋: Metro スタイルアプリ「くじ庵」制作記

Community Open Day 2012 の名古屋会場で「Metro アプリの作り方」を喋って、 ほっと一息ついたところで。

@jz5 さんから、 指令ががが!!

え~~~っ!? いやさすがに5分はムリ杉だからっ!! (@@;

でもまぁ、 LT では途中の状態をお見せして、 プレゼント抽選タイムには何とか間に合わせることができましたよ、っと!
ふぅ~ (汗;

Kujian01

  • [START] ボタンで、 選択状態がどんどん下へ移動していく。 一番下まで行ったら、 一番上に。
  • [STOP] ボタンで、 移動速度がゆっくりになっていき、 数秒後に停止。 点滅して、 当選を知らせる。
  • [NEXT] ボタンで、 当選者をリストから抜き、 表示を初期状態に戻す。

てことで、 以下だらだらと制作記録など。
※ ソースコードは SkyDrive に。 ⇒ http://sdrv.ms/Kj4QnC

■ オーダー

  • 参加者の中から当選者を選ぶ、くじ引きアプリ
  • 続けてくじ引きを実施できる
  • 同じ人は1回しか当選できない

■ 構想

  • 名前: くじ引きと言われたら、あんばらんすと答えるのが常識というものですw
  • 参加者データは、atnd のページから html ソースの一部を持ってきて取り込めばいいだろう。 上手くできなかったら、しょうがない、まぁ40人分くらいだからひとりずつコピペしても、 なんとかなる。
  • 見た目は、いきなり当選者が表示されても面白くないよね。
  • どんどん参加者が流れて行って、STOPを掛けるとしばらくして止まる、ってのはどう?
  • 無限に流れるのは面倒、 つか、 時間的にムリ。 なんとか誤魔化せんか… ListViewで下までいったら上に戻る動きでどうよ。
  • ListViewなら、「Split App (XAML)」プロジェクトに使えそうな画面があるぞ!

■ 実装

◆ 参加者データ

・atnd の html ソースからコピペして、 ダブルクォートを二重にするとかの置換をした上で、 ソース中に埋め込み。
・参加者オブジェクトは、 とりあえず Name プロパティと ImageUrl プロパティを持ってればよさげ。
・参加者クラスは、 Create() 静的メソッドを呼び出せば、 参加者オブジェクトの IList を返してくれればいい。
・html ソースがちゃんと xml になってれば、 XDocument クラスを使って名前とかを切り出せるハズ。
  (ダメなら、RegEx のお世話になるか!?)

◆ XAML (画面)
・新規作成で、 「Split App (XAML)」プロジェクトを作ってみる。 その中で、 2番目に表示される SplitPage.xaml は、 こんな感じ。
Kujian02

・右側の ScrollViewer の中身を隠してしまって、 左側の ListView だけ使えば、 それっぽくなるだろう。 itemDetailGrid の Visibility を "Collapsed" にする。
※ ざっくり削除してしまうと、 たぶんあっちこっとで itemDetailGrid を参照してるはずなんで、 修正がタイヘン。

・ListView のテンプレートを SplitPage.xaml にコピーしてきて、 フォントを大きくしてみたり。

 

☆ このへんで LT タイム。 ここまでの過程を、 しどろもどろに解説した f(^^;

 

・画面右上に、 ボタンを 3つ追加。

※ ボタンの Click イベントも書いてあるけど、 それは後から。
※ 最初、 デバッグ実行でクリックしても反応が無いので、 すげ~あせった。 ScrollViewer の中身を隠したんだけど、 レイヤーとしては存在していて、 それにマウスクリックが阻まれていたらしい。 ScrollViewer の位置を下げて、 解決 f(^^;

これで画面はこんな感じに。
Kujian03
※ 実際には、 この時点での表示用データはまだ元のままなので、 こんなふうに参加者の名前は出ない。

◆ 画面表示

このプロジェクトテンプレートでは、 最初に ItemPage が表示されるようになっている。ので、 それを SplitPage に変更。
App.xaml.cs で
if (!rootFrame.Navigate(typeof(ItemsPage), "AllGroups"))

if (!rootFrame.Navigate(typeof(SplitPage), "Group-1"))

◆ 表示用データ

元のソースでは DataModel/SampleDataSource.cs のコンストラクタで、 ハードコーディングでデータを突っ込んでいる。

ここを、 作った参加者クラスを使ってデータを叩き込むように変更。
※ 注: 本来は SampleDataSource クラスをきちんと変更するべきところ。 それやると、 修正個所が大量に出てしまう (ハズ) なので、 ここは手抜きでデッチ上げるw

これでビルドすると、 なんとデザイン画面にも反映される!! (前出の画像)

◆ コードビハインド

MVVM とか格好良いことを言ってる余裕はないので、 SplitPage.xaml のコードビハインドにイベントハンドラーを作って、 コードを書いて行っちゃう f(^^;

◇◇ START ボタン

フラグ立てて、 一定間隔でどんどん次のリストアイテムを選択してやればいいわけですな。
ただし、 STOP ボタンの処理中 (_isBreaking フラグが立ってる間) は待つ、 と。
今までの発想だとタイマー割り込みを使う場面ですが、 こういうところでも async / await を使って読みやすく書けます。

※ あ~、 バグってますねw Rotete() メソッド内で _isContinue フラグを立てるのは、 最初の while ループの後じゃないとイカン。

◇◇ STOP ボタン

フラグを倒して Rotete() が終わるのを待って、 そしたら、 時間間隔を多少ランダムに延ばしながら 5秒ほど回す。 で、 止まったら点滅させて、 最後に背景色を変えて止まったことを示す。

※ START ボタンを実装してるあたりかなぁ、 ネットワークが切れちゃった (抽選会の前に復旧できたけど)。 ので、 止まった時に音を出したかったけど、 ぐぐることかなわず。 うろ覚えの記憶では、 実装できなかった… orz

◇◇ NEXT ボタン

これは簡単、 itemListView から現在 Selected になっている要素を削ればいい。
…と思ったら。 itemListView.Items.Remove(itemListView.SelectedIted) ではダメなんだと… (ToT)
ぐぐれないのでかなり冷や汗をかいたけど、 なんとか正解に辿り着けた f(^^;


これで、 完成! (^^)

 

■ 仕様追加

え~、 まいどおなじみ、 仕様変更のお時間でっすw
@jz5「参加者の並び順はランダムにしてね!」

ぅ… itemListView が持ってるデータを引っ張り出して、 ランダムに入れ替えてやればいいんだろうけど、 ちとかなり時間がかかりそう…。 てことで、 [NEXT] 時にランダムにするのは勘弁してもらって、 最初だけにする。
それなら、 参加者データを作るところで細工すれば OK f(^^;



これでほんとに完成 f(^^;
最後に、 実装中にやってなかったテスト (最後の一人で START / STOP / NEXT しても大丈夫だよね) も確認して、 いちおう終了。

このあと、 なんとか音を出したいとジタバタしてみたけど、 ネットーワークが切れてる状態では MSDN が見えないってことで、 オブジェクトブラウザーだけではどうにもこうにも…。 そんなわけで、 音が無くてちょっと寂しかったけど、 無事に抽選会には使ってもらえました f(^^;

|

« [Metro] {プロジェクト名}_TemporaryKey.pfx が無い! | トップページ | Windows 8 RTM が MSDN で公開 ~ さぁ、 Metro アプリを作ろう! »

プログラミング」カテゴリの記事

-プログラミング ( VS2012 )」カテゴリの記事

* プログラミング ( Metro スタイル )」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: #cod2012jp 名古屋: Metro スタイルアプリ「くじ庵」制作記:

« [Metro] {プロジェクト名}_TemporaryKey.pfx が無い! | トップページ | Windows 8 RTM が MSDN で公開 ~ さぁ、 Metro アプリを作ろう! »