あいてぃーとふぼふ

WP7のPivotの中のScrollViewer

今日は凄くニッチなお話です。Pivotコントロールの中にScrollViewerを配置して、横長のコンテンツを水平スクロールできるようにしようとしたのですが、これが一筋縄ではいきませんでした。

上記の構成において、ScrollViewer上で水平フリックを行うと、親のPivotにも水平フリックが伝達されてしまいます。このため、結果としてPivotが意図せず遷移してしまうのです。これは困りましたね~(;´∀`)

…え?そんなことする状況なんてめったにないからどうでもいい?とんでもない!(゚Д゚#)たとえば、上記の画像の右端にはまだ続きがあるのですが、水平スクロールさえできればパンツ続きが見れるとしましょう!こんな状態で勝手にPivotが遷移しようものなら、ユーザビリティの低下なんて生易しいものじゃありません。営業妨害です!ここでいうところのユーザビリティがどんなものであるかは敢えて触れませんが、これは死活問題なのです!(`Д´)

でも解決方法は意外と簡単で、ScrollViewerのManipulationCompletedイベントを利用して、水平スクロールが完了するまでPivotにイベントが伝達されないようにすればOKです。ソースコードはこんな感じですね。

private void ScrollViewer_ManipulationCompleted(
object sender, ManipulationCompletedEventArgs e)
{
var scrollViewer = sender as ScrollViewer;
e.Handled = e.TotalManipulation.Translation.X > 0 ?
scrollViewer.HorizontalOffset > 0 :
scrollViewer.HorizontalOffset + scrollViewer.ViewportWidth < scrollViewer.ExtentWidth;
}

この程度ならビヘイビアにしなくてもよさそうですが、せっかくなのでサンプルコードはビヘイビアとして作成してみました。詳細な実装方法が知りたい方や、画像の右端が気になるという方は、以下のサンプルコードをどうぞ。
ScrollViewerOnPivotSample

今日は3年ぶりにSODEC(ソフトウェア開発環境展)に行ってきます~( ´∀`)

WP7のスプラッシュスクリーン

スプラッシュスクリーンとは、アプリケーションを起動した時に初期化が完了するまで表示される画面のことです。Now Loading…的なアレですね。

WindowsPhone7のSilverlightアプリでは、スプラッシュスクリーンとして『SplashScreenImage.jpg』が表示される仕様になっています。しかしこれは逆に、上記のJPEG画像以外をスプラッシュスクリーンに指定することができないことを意味します。

通常ならこれでも何ら問題はないのですが、初期化処理に時間がかかるような場合などでは、どうしてもスプラッシュスクリーンをアニメーションさせたくなります。たとえば何秒間も同じ画像がただ表示されているよりも、砂時計が回っていたりしてくれた方がユーザさんは安心できるわけです。ところが、WindowsPhone7アプリでは上記の仕様が存在するため、スプラッシュスクリーンでアニメーションを再生させることはできません。これはションボリものです(´・ω・`)ので、これを解決するための方法として以下のような力技はいかがでしょうか?

プロジェクトの構成

まずプロジェクトを以下のような構成とします。AとBはプロジェクト作成時に生成されますので、新規に追加するのはCとDのユーザコントロールです。Cには初期化中に表示するアニメーションを定義し、 Dには初期化後に操作の起点となるコントロールを配置します。この際、AとCは似た構成にしておくと、アニメーションが違和感なく開始されていい感じになります。

  • A:SplashScreenImage.jpg
  • B:MainPage.xaml
  • C:SplashScreenContent.xaml
  • D:MainContent.xaml

処理の流れ

処理の流れは以下のような感じです。

  1. アプリケーションが起動されるとAが表示され、次いでBが表示されます。
  2. 次に、BのLayoutRootにCを設定して、初期化処理を実施している間アニメーションを再生します。
  3. 初期化処理が完了したら、BのLayoutRootにDを設定して完了です。

注意するべき事柄

『SplashScreenContent.xaml』をページとして作成すればもっとスマートに実現できそうですが、その方法だと『MainPage.xaml』で戻るボタンが押下された際に、再度スプラッシュスクリーンが表示されてしまいます(通常はアプリケーションが終了しなければいけません)。あと『MainContent.xaml』にPanoramaコントロールを利用する場合、LayoutRootに設定する直前にインスタンスを生成する必要があります。これはPanoramaコントロールに設定されている既定のトランジション(画面遷移効果)がインスタンスの生成時に開始されるためです。

サンプルプログラム

…なんか文章で書いてもあまり伝わらないので、よろしければサンプルプログラムもご覧ください(; ̄ー ̄
SplashScreenSample

将来的には?

現在のバージョンでは『SplashScreenImage.jpg』以外をスプラッシュスクリーンに指定することはできませんが、ビルドアクションには既に『SplashScreen』が定義されています(WPFなどの名残かもですが…)。なので将来的にはPageや他のメディアなどをSplashScreenに指定することができるようになるとうれしいですね~!(≧ω≦)