• 検索結果がありません。

グラフィックス 目次

N/A
N/A
Protected

Academic year: 2021

シェア "グラフィックス 目次"

Copied!
21
0
0

読み込み中.... (全文を見る)

全文

(1)

■ 第10 回 WPF の「入力イベントとアニメーション」を学ぼう ■ 今回は入力イベントとアニメーションについて説明していく。

前回までの説明は、Visual Studio の無償版である Visual C# Express や Visual Basic Express でも試 すことができた。しかし、今回は、有償製品のExpression Blend の利用が前提となる説明が多くなっ ている。その点ご容赦いただきたい。Expression Blend を利用するのは、Visual Studio にはアニメー ションを視覚的に編集する機能がないためだ。 一応、視覚的な編集ツールが不要で、Expression Blend 付属のライブラリだけなら、無償で入手可能な Blend SDKをインストールすれば利用可能である。 * 本稿での「ユーザー」という表記はすべて、WPF アプリケーションを利用する「エンド・ユーザー」 を指す。 ■ 入力 連載第6 回で説明したように、モデル(=見た目と関係なく成り立つロジックやデータ)に対するイベ ント通知はコマンド(=意味論的なイベント処理機構)という層を通して行うことが多く、この用途で 入力イベントを直接処理する機会は多くないだろう。入力イベントは以下のような場面で利用すること になる。 ・コマンド・ソースとなるユーザー・コントロールを自作する ・アニメーション開始などのトリガーとして使い、インタラクティブなビューを作成する 入力に関連するクラス WPF では、キー入力関連なら Keyboard クラス、マウス入力関連なら Mouse クラス(いずれも System.Windows.Input 名前空間)というように、入力デバイスの種類ごとにルーティング・イベント を 定 義 す る ク ラ ス が 存在 す る 。 例 え ば 、 キー・ ダ ウ ン ・ イ ベ ン トの場 合 、Keyboard クラスの KeyDownEvent ルーティング・イベントが発生する。

また、UIElement クラス(System.Windows 名前空間)には、UI 要素がこれらのルーティング・イベ ントを受け取ったときに発生するCLR イベントが定義されている。従って、XAML コード中では、以 下のような2 通りのイベント・ハンドラ登録の方法がある。 <!-- Keyboard クラスのルーティング・イベント(添付イベント) --> <TextBox Keyboard.KeyDown="TextBox_KeyDown" /> <!-- UIElement クラスのイベント --> <TextBox KeyDown="TextBox_KeyDown" /> キー入力を処理するための2 種類のイベント・ハンドラ(XAML) ※ 「添付イベント(attached event)」とは、添付プロパティのルーティング・イベント版のようなも ので、ほかのクラスで定義されているルーティング・イベントを受け取って処理するための機構で

W

W

P

P

F

F

(2)

ある。 バブル・イベントとトンネル・イベント 入力イベントにはバブル・イベントとトンネル・イベント(第6 回参照)があり、トンネル・イベント の名前には語頭に「Preview」が付いている(付いていないものはバブル・イベント)。例えば、キー・ ダウンなら、バブル・イベントが「KeyDown」、トンネル・イベントが「PreviewKeyDown」となる。 コントロールなどでは、バブル・イベントを「処理済み」(=それ以上イベントが親要素に伝搬(でん ぱ)しない)にしてしまうものがある(例えば、ボタンはマウス・クリックを、テキストボックスはキ ー・ダウンを処理済みにする)。子要素の種類によらず、親要素側でイベントを拾いたい場合にはトン ネル・イベント(=Preview で始まるイベント)を利用する。 次節からは個々のイベントについて、主要なものを紹介していこう。1 つの入力イベントに対して関連 するプロパティやメソッド、イベントが複数あるが、命名規則は一貫しているので使い分けは難しくな い。次節以降では、例えば、「Keyboard クラスの KeyDown イベント」といった場合、以下のようなも のが存在するものと読み替えてほしい。 ◆ Keyboard クラス中: ・KeyDownEvent 静的プロパティ ・AddKeyDownHandler 静的メソッド ・RemoveKeyDownHandler 静的メソッド ◆ UIElement クラス中: ・OnKeyDown メソッド ・KeyDown イベント また、「Preview」を付けることでトンネル・イベントとなるので、バブル・イベントのみを紹介する。 キーボード Keyboard クラス(System.Windows.Input 名前空間)に以下のようなイベントが定義されている。 ○キー ・KeyDown: キーを押したときに発生する。 ・KeyUp: キーを離したときに発生する。 どのキーが押されたかは、イベント・ハンドラの第2 引数(KeyEventArgs クラス)の Key プロパティ で取得できる。また、KeyEventArgs クラスには KeyboardDevice プロパティ(KeyboardDevice クラ ス)があり、これを介して[Shift]キーなどの修飾キーに関する情報も取得できる。

○フォーカス

・GotKeyboardFocus: UI 要素がキーボード・フォーカスを得たときに発生する。 ・LostKeyboardFocus: UI 要素がキーボード・フォーカスを失ったときに発生する。

(3)

また、イベント駆動ではなく、能動的にキーボードの状態を調べるために、Keyboard クラスには IsKeyDown や GetKeyStates などの静的メソッドも定義されている。 ○キーボード・フォーカスと論理フォーカス WPF のフォーカスには、以下のように、2 種類の概念が存在する。 ・キーボード・フォーカス: 実際にキーボードからの入力を受け取れる状態。デスクトップにあるす べてのウィンドウの中で1 つの UI 要素だけがキーボード・フォーカスを持つ。 ・論理フォーカス: フォーカス範囲(=通常は 1 つのウィンドウが 1 つのフォーカス範囲を持つ)ご とに1 つの UI 要素が論理フォーカスを持つ。一度アクティブでなくなったウィンドウが再度アクテ ィブになった際、論理フォーカスを持つUI 要素がキーボード・フォーカスを得る。

Keyboard クラスの GotKeyboardFocus イベントおよび LostKeyboardFocus イベントはキーボード・ フ ォ ー カ ス の 取 得 / 消 失 で 発 生 す る イ ベ ン ト で あ る 。 一 方 で 、 論 理 フ ォ ー カ ス に 関 し て は 、 FocusManager クラス(System.Windows.Input 名前空間)に以下のようなイベントが定義されている。 ・GotFocus: UI 要素が論理フォーカスを得たときに発生する。 ・LostFocus: UI 要素が論理フォーカスを失ったときに発生する。 Movie 1 にキーボード・フォーカスと論理フォーカスの差を確認する例を示す。 https://www.youtube.com/watch?v=LCUlTyKfwQE&feature=player_embedded Movie 1: キーボード・フォーカスと論理フォーカスの例 この例では、フォーカスを得た瞬間にアニメーションを開始するようにしてある。テキストボックスを 移動した際にはキーボード・フォーカスと論理フォーカスの両方が変化するのに対して、ウィンドウを 切り替えた際にはキーボード・フォーカスだけが変化する。 テキスト入力 キーボードからのキー入力とは別に、キーボード/手書き認識/音声認識のいずれの入力かを問わない テキスト入力のためのイベントとして、TextCompositionManager クラス(System.Windows.Input 名 前空間)に以下のイベントが定義されている。 ・TextInputStart: テキスト入力を開始したときに発生する。 ・TextInputUpdate: テキスト入力の状態が変化したときに発生する。 ・TextInput: テキスト入力が完了したときに発生する。

TextInputStart イベントや TextInputUpdate イベントを利用すれば、IME による日本語変換の途中の 状態を取得することもできる。

Movie 2 に、音声認識、手書き認識、および、IME 経由によるテキスト入力の例を示す。 https://www.youtube.com/watch?v=44L9HV9G0wE&feature=player_embedded

(4)

TextInput イベントが起こるたびに、入力されたテキストを右側のリストボックスに追加している(左 側はただのテキストボックス)。 マウス Mouse クラス(System.Windows.Input 名前空間)に以下のようなイベントが定義されている。 ○マウス・ボタン/ホイール ・MouseDown: マウス・ボタンを押したときに発生する。 ・MouseUp: マウス・ボタンを離したときに発生する。 ・MouseWheel: ホイール操作を行ったときに発生する。 これらMouse クラスで定義されているイベントのほかに、UIElement クラスでは以下のようなイベン トが定義されている。 ・MouseLeftButtonDown/MouseLeftButtonUp: マウスの左ボタンのダウン/アップで発生する。 ・MouseRightButtonDown/MouseRightButtonUp: マウスの右ボタンのダウン/アップで発生する。 マウスの左ボタンを押した際にはMouseDown イベントと MouseLeftButtonDown イベントの両方が 発生するので利用の際には注意が必要である。 ちなみにダブル・クリックに関するイベントは、UIElement クラスにはなく、Control クラスで MouseDoubleClick イベントが定義されている。 ○マウス移動 ・MouseEnter: マウス・ポインタが UI 要素の上に乗った瞬間に発生する。 ・MouseMove: マウス・ポインタが UI 要素上を動くか、キャプチャ中のマウスが動いた場合に発生 する。 ・MouseLeave: マウス・ポインタが UI 要素上から離れた瞬間に発生する。 ・GotMouseCapture: マウスがキャプチャ開始された瞬間に発生する。 ・LostMouseCapture: マウスのキャプチャが解除された瞬間に発生する。 マウスのキャプチャ(=マウス・ポインタの位置によらず、コントロールがすべてのマウス入力コマン ドを受け取るようにようにマウスを捕捉すること)は、UIElement クラスの CaptureMouse メソッド で、キャプチャ解除はReleaseMouseCapture メソッドで行う。

また、マウス・ポインタの位置は、Mouse クラスの GetPosition 静的メソッドか、MouseDevice クラ ス(=イベント・ハンドラの第2 引数からオブジェクトを取得可能)の GetPosition メソッドを使って 取得できる。GetPosition メソッドは、引数に UI 要素を与えることで、その UI 要素の左上座標を起点 とした相対座標を取得する。

【コラム】マウス・カーソルの形状を変化させるには?

UI 要 素 上 に マ ウ ス ・ ポ イ ン タ を 乗 せ た と き に 、 カ ー ソ ル の 形 状 を 変 化 さ せ た い 場 合 、 FrameworkElement クラス(System.Windows 名前空間)の Cursor プロパティを利用する。Cursor プロパティに指定するカーソルは、Cursor クラスのコンストラクタで Windows のカーソル・ファイ

(5)

ル(拡張子は「.cur」や「.ani」)を読み込んだものか、Cursors クラス(System.Windows.Input 名 前空間)の静的プロパティとして定義されている標準カーソルのいずれかを利用する。

また、FrameworkElement クラスの ForceCursor プロパティの値を「true」にすることで、(子要素 でのCursor プロパティの設定を無視して)自身の Cursor プロパティの値を強制することができる。 ドラッグ&ドロップ DragDrop クラス(System.Windows.Input 名前空間)に以下のようなイベントが定義されている。 ・DragEnter/DragOver/DragLeave: ドラッグ中のマウス・ポインタが UI 要素上に乗った瞬間/ 動いたとき/離れた瞬間に発生する。 ・Drop: ドロップされると発生する。 ・GiveFeedBack: ドロップ・ターゲットからドロップ・ソースへのフィードバック用のイベント。 ・QueryContinue: ドラッグ&ドロップ操作中にキーボード操作などがあったときに、ドラッグ&ド ロップ操作を続けるかどうかを判断するためのイベント。 スタイラス Stylus クラス(System.Windows.Input 名前空間)にスタイラス関連のイベントが定義されている。 スタイラスはマウスとしても認識される(=スタイラス・イベントと同時にマウス・イベントが発生す る)ため、スタイラス固有の機能を利用しない場合にはマウス・イベントの処理だけでもアプリケーシ ョンを作成できる。

MouseDown イベントに対して StylusDown イベントがあり、CaptureMouse メソッドに対して CaptureStylus メソッドがあるなど、マウス・イベントから類推できるスタイラス・イベントも多い。 一方、スタイラス固有のイベントとしては以下のようなものがある。 ・StylusInrange/StylusOutOfRange: スタイラスがタブレット範囲に入った/離れた瞬間に発生す る。 ・StylusInAirMove: スタイラスをタブレットから浮かせながら移動させたときに発生する。 ・StylusSystemGesture: スタイラス・ジェスチャ*1 をユーザーが実行したときに発生する。 *1 スタイラス・ジェスチャとは、例えばタップやドラッグなどのこと。利用可能なジェスチャについ ては、SystemGesture 列挙体(System.Windows.Input 名前空間)のメンバを参照してほしい。 マルチタッチ Windows 7 のマルチタッチ対応に合わせて、WPF 4 でタッチ・イベントが追加された。WPF 4 では方 針が変更されたようで、マウス・イベントでいうところの Mouse クラスに相当する Touch クラスや Manipulation クラス(いずれも System.Windows.Input 名前空間)にはルーティング・イベントが (public には)定義されていない。UIElement クラスに TouchDown などのイベントが定義されている ので、これらを利用する。

マルチタッチ・デバイスに関連したイベントには以下の2 つの種類がある。

(6)

・操作(manipuration)イベント: タッチ・ジェスチャ*2 による回転・拡大・平行移動などの、一段 階抽象度の高い情報が得られるイベント。 *2 タッチ・ジェスチャとは、例えばパンやズームなどのこと。詳しくは、windows.microsoft.com の 「Windows 7 タッチ ジェスチャ」を参照してほしい。すなわち、操作イベントとは、フレームワーク 上でタッチ・イベントを要約して、平行移動や拡大/縮小などの、プログラマーに分かりやすい情報に 変換してからイベントを発生させるものである。 前者のタッチ・イベントは、スタイラス同様、マウス・イベントも発生させるため、マウス・イベント の処理だけでもある程度のアプリケーションを作成できる。イベント名も、MouseDown イベントに対 してTouchDown イベントがあるなど、マウス・イベントから類推可能である。 一方、操作イベントには以下のようなものがある。 ・ManipulationStarted: ユーザーがタッチ操作を開始したときに発生する。 ・ManipulationStarting: タッチ操作可能な UI 要素(=IsManipulationEnabled プロパティの値が 「true」)に対してユーザーがタッチ操作を開始したときに発生する。 ・ManipulationInertiaStarting: ユーザーが慣性操作(=勢いよく指を動かしたときに、しばらく慣 性的にManipulationDelta イベントが起きる)を開始したときに発生する。 ・ManipulationDelta:ユーザーが指を動かしてタッチ操作に変化が生じたときに発生する。 ・ManipulationCompleted: ユーザーがタッチ操作を終えたときに発生する。 ・ManipulationBoundaryFeedback: 操作対象の UI 要素がタッチ操作可能な範囲の境界に到達した ときに発生する。 Movie 3 に操作イベントの利用例を示す。 https://www.youtube.com/watch?v=Esy90BTRf4w&feature=player_embedded Movie 3: 操作イベントの例 この例では、Blend SDK 付属の TranslateZoomRotateBehavior を利用して、操作イベントに応じて UI 要素の回転・拡大・平行移動を行っている。詳細は本稿の後半で説明するが、動画を見てのとおり、 UI 要素にビヘイビアを付与する(Expression Blend 上ではドラッグ&ドロップ操作で付与可能)だけ で、操作イベントに応じて回転・拡大・平行移動ができる。 ■ アニメーション WPF のアニメーションは以下のような特徴を持っている。 ・実時間ベース: フレーム・レート(=1 秒間に描画されるコマ数のこと)が変わっても再生速度は変 わらない。

・マークアップ・ベース: XAML コード中に記述でき、Expression Blend などのツールでの読み書き が容易。

低レベルなアニメーション制御

WPF では、後述するストーリーボードという高機能なアニメーション制御機構を利用できるが、一応、 低レベルなアニメーション制御の仕方についても補足説明しておこう。

(7)

まず、最も原始的なアニメーション制御の仕方として、UI 要素の描画タイミングを拾って、すべて自 前でアニメーションを管理する方法が考えられる。描画タイミングは、CompositionTarget クラス (System.Windows.Media 名前空間)の Rendering 静的イベントによって拾うことができるので、こ のイベントを利用することになる。 次に、PresentationCore アセンブリ(=WPF 以外のフレームワークでも利用することを想定した汎用 的な機能のみを集めた部分)レベルでは、TimeLine クラス(System.Windows.Media 名前空間)や、 UIElement クラスの BeginAnimation メソッドなどを利用することで、UI 要素ごとのアニメーション を制御できる。ただし、この方法ではXAML コード中に記述できず、分離コードが必要となる。 次節以降で説明するストーリーボードは、PresentationFramework アセンブリ(=WPF 固有の機能) レベルのアニメーション制御機構である。 ストーリーボード 多くの場合、1 つの UI 要素だけをアニメーションさせることはほとんどなく、複数の UI 要素が絡むこ とになる。そこで、「どのUI 要素をどのタイミングで動かすか」という情報を複数まとめて管理するも の を ス ト ー リ ー ボ ー ド ( storyboard : 絵 コ ン テ ) 呼 び 、 Storyboard ク ラ ス (System.Windows.Media.Animation 名前空間)がその役割を担う。 ストーリーボードは、XAML コードとして記述できるので、原理的には「メモ帳で編集可能」なもので ある。しかし、複雑なストーリーボードは最終的な XAML コードも複雑になり、編集ツールのサポー トなしでは厳しいだろう。残念ながら、Visual Studio ではストーリーボードの編集が容易ではなく、 Expression Blend の利用がほぼ必須といえる。Movie 4 に、Expression Blend を利用したストーリー ボード編集の例を示す。

https://www.youtube.com/watch?v=-5B1VyFgctI&feature=player_embedded Movie 4: Expression Blend を利用したストーリーボードの編集の例

この例では、だ円を左右に振動させるストーリーボードを作っている。また、後述するビヘイビアを使 って、だ円の上にマウス・ポインタが乗った瞬間にストーリーボードの再生を開始するよう設定してい る。 ○ストーリーボードの内容 Movie 4 に示した編集の結果となるストーリーボードを List 1 に示す。 <Storyboard x:Key="ShakeStoryboard"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="ellipse">

<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="10"> <EasingDoubleKeyFrame.EasingFunction>

<CircleEase EasingMode="EaseIn"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame>

(8)

<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="-20"/> <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="20"/> <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="-20"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="-0"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> </DoubleAnimationUsingKeyFrames> </Storyboard> List 1: ストーリーボードの例 こ の 例 で は ス ト ー リ ー ボ ー ド の コ ン テ ン ツ で あ る タ イ ム ラ イ ン ( = <DoubleAnimationUsingKeyFrames>要素など)は 1 つしかないが、Figure 1 に示すように、ストー リーボードは複数のタイムラインを持つことができる。 Figure 1: ストーリーボードとタイムライン 各タイムラインは、Figure 2 に示すように、「どのUI 要素のどのプロパティを、どう動かすか」という 情報を持っている。動かし方ごとに異なるクラスとなっている。

(9)

Figure 2: タイムラインの構成と種類

ちなみに、TargetProperty 属性には、データ・バインディングで使う Binding マークアップ拡張の Path プロパティと同様の構文でパスを指定する(第5 回参照)。 ○キー・フレームを使ったタイムライン Expression Blend での編集結果として得られるために最も目にする機会が多くなる、キー・フレームを 使ったタイムライン(=型名が UsingKeyFrames で終わっているタイムライン)について、もう少し 詳しく説明しておこう。 キー・フレームとは、アニメーションにおける変化の基点となるフレーム(=いわゆる「コマ」)のこ とをいう。アニメーションは、いわゆるパラパラ漫画の要領で、1 フレームごとに位置や色などを指定 することでも制御可能である。しかし、この方法には以下のような問題がある。 ・アニメーションが長くなると、位置や色などの情報が膨大になる ・フレーム・レート(=1 秒間に何回描画を行うか)の変化への対応が難しい(処理落ちなどでフレー ム・レートが落ちた場合、アニメーションがスローモーション再生されるというようなことがある) そこで、WPF では、とびとびにキー・フレームというものを設定し、位置や色などの情報はキー・フ レームに対してだけ行い、その間の値は補間によって生成することでアニメーションを制御している。 補間は時刻に応じて行われるため、フレーム・レートが変化してもアニメーションの再生速度は変わら ない。それでは、具体的なキー・フレームの設定方法を見ていこう。WPF では、、Figure 3 に示すよう に、「どの時刻までにどういう値になっているべきか」と「値の補間方法」を指定する。 Figure 3: キー・フレームの構成と種類

(10)

図中の4 つの補間方法はそれぞれ以下のようなものである。 ・Discrete: 指定時刻になった瞬間に、離散的に値を変化させる。要するに、補間は行われず、値は指 定時刻に一気に切り替わる。 ・Linear: 線形補間。値は一定速度で徐々に変化していく。 ・Spline: スプライン曲線を用いた補間。値を滑らかに変化させることができ、線形補間(=一定速 度の直線的な動きしかできない)を利用する場合よりキー・フレームの間隔を長めに取っても自然な 動きを実現しやすい。

・Easing: 任意の関数を使って補間。補完に使う関数のことをイージング関数(easing function: easing は「急な変化を緩和する」という意味)と呼ぶ。WPF 4 で追加された。 イージングに使う関数は、もちろん自作することもできるし、いくつかのイージング関数は標準で提供 されている。標準提供されているものには、例えば、ボールが弾むような軌跡を描く「BounceEase」 関 数 や 、 バ ネ の 伸 び 縮 み の よ う な 軌 跡 の 「 ElasticEase 」 関 数 ( い ず れ も System.Windows.Media.Animation 名前空間)などがある。以下のデモが参考になるだろう(Silverlight に関するデモだが、イージング関数の種類はWPF でも同様である)。 ・MSDN 上で公開されている「イージング関数ギャラリー」 トリガー ストーリーボードを定義しただけではアニメーションは開始されず、別途、開始や停止のきっかけ(= 「トリガー」と呼ぶ)が必要である。 WPF では、もともと、FrameworkElement クラスの Triggers プロパティを使ってトリガーを設定す ることができた。例えば、<Window>要素の直下に以下のような XAML コードを記述することで、ウ ィンドウのロード完了と同時にストーリーボードを開始できる。 <Window.Triggers> <EventTrigger RoutedEvent="Loaded">

<BeginStoryboard Storyboard="{StaticResource ShakeStoryboard}" /> </EventTrigger> </Window.Triggers> ウィンドウのロード完了と同時にストーリーボードを開始するコード例(XAML) 標準で提供されているトリガーには、主に、以下のようなものがある。 ・EventTrigger: ルーティング・イベントが発生したときにアクションを実行する。 ・DataTrigger: 指定したプロパティの値が変化したときにアクションを実行する。 ・MultiDataTrigger: 複数の値をトリガーにしてアクションを実行する。 また、アクション(=トリガーがかかったときに実行される内容)の代表的なものとしては以下のよう なものがある。 ・BeginStoryboard: ストーリーボードを開始する。 ・PauseStoryboard: ストーリーボードを一時停止する。 ・SoundPlayerAction: 音声を再生する。

(11)

ちなみに、Expression Blend では、この Triggers プロパティを使った仕組みではなく、次節で説明す るビヘイビアという仕組みを使ってトリガーを掛けることになる。 ■ ビヘイビアとインタラクション・トリガー Movie 3 や Movie 4 では、ストーリーボード開始のトリガーを設定したり、マルチタッチに応じて回転・ 拡大・平行移動を掛けたりするために、「ビヘイビアー」と書かれたパネルから何かをUI 要素にドラッ グ&ドロップしていることが見て取れるだろう。 このパネルに並んでいるものは、「トリガー」や「ビヘイビア(behavior: 振る舞い)」と呼ばれるも のである。トリガーは、WPF 標準機能にも同名で、機能的にも同様のものがあるが、Expression Blend 付属のライブラリではWPF 標準のものよりも少し機能が多い、別の「トリガー」が実装されている。 WPF 標準のものと区別するために、ここでは Blend 付属のトリガーを、便宜上、「インタラクション・ トリガー」と呼ぶことにする(トリガーが定義されているクラスの名前が「Interaction」であるため)。 インタラクション・トリガー インタラクション・トリガーは、もともと、FrameworkElement クラスに Triggers プロパティがない Silverlight において利用するために、添付プロパティとしてトリガーの仕組みを実装し直したものだが、 WPF にも逆輸入されている。

Expression Blend を利用する場合には WPF でも(Triggers プロパティではなく)インタラクション・ トリガーを使うことになるし、そうでない場合にも、こちらを使えば Silverlight への移植が楽になる だろう。

また、WPF の標準のトリガー(=Triggers プロパティ)を使ったものよりも、Expression Blend SDK 付属のインタラクション・トリガーの方が多彩なトリガーを持っている。例えば、以下のようなトリガ ーがある。 ・TimerTrigger: タイマーに基づいてアクションを実行する。 ・StoryboardCompletedTrigger: ストーリーボードの完了をトリガーとしてアクションを実行する。 同様に、アクションの種類も増えている。一例を挙げると以下のとおりである。 ・ChangePropertyAction: プロパティの値を変更する。 ・NavigateToPageAction: ページ間のナビゲーションを指定する。 ・GoToStateAction: 後述するビジュアル・ステート(=外観状態)を変化させる。 ・InvokeCommandAction: コマンドを実行する。 ビヘイビア 一方、ビヘイビアは、名前どおり、UI 要素の振る舞いを XAML コードとして記述できるように(= Expression Blend のようなツールを使ってドラッグ&ドロップ開発できるように)カプセル化したもの である。例えば、Blend 標準では以下のようなものがある。 ・FluidMoveBehavior: ウィンドウ・サイズの変更などで UI 要素のレイアウトが変化した際に、UI 要素が滑らかに移動するようになる。

(12)

・MouseDragElementBehavior: マウス・ドラッグで UI 要素を移動できるようになる。

・TranslateZoomRotateBehavior: マルチタッチ操作イベントに応じて UI 要素を回転・拡大・平行 移動できるようになる。

FluidMoveBehavior および MouseDragElementBehavior の利用例をそれぞれ Movie 5 および Movie 6 に示す。 https://www.youtube.com/watch?v=WrwbykPQHgA&feature=player_embedded Movie 5: FluidMoveBehavior の利用例 https://www.youtube.com/watch?v=R8OREojNQjo&feature=player_embedded Movie 6: MouseDragElementBehavior の利用例 ○ビヘイビアの自作 Behavior クラス(System.Windows.Interactivity 名前空間)を継承したクラスを作ることで、ビヘイ ビアの自作も可能だ。 例えば、日本の業務アプリケーションではよくある要件だが、[Tab]キーの代わりに[Enter]キーで フォーカス移動することを考えてみよう。List 2 に示すようなコードで、このような動作をするビヘイ ビアを作ることができる。List 3 にこのビヘイビアの利用例を示す。 XAML <Grid> <i:Interaction.Behaviors> <l:FocusMoveBehavior Key="Enter" /> </i:Interaction.Behaviors> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <TextBlock Text="A" /> <TextBox Grid.Column="1" />

<TextBlock Text="B" Grid.Row="1" /> <TextBox Grid.Row="1" Grid.Column="1" />

<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.ColumnSpan="2"> <Button Content="OK" />

<Button Content="Cancel" /> </StackPanel>

(13)

Visual Basic

Imports System.Windows.Input

Imports System.Windows.Interactivity Imports System.Windows

Namespace atmarkit10

Public Class FocusMoveBehavior Inherits Behavior(Of UIElement) Public Property Key() As Key

Protected Overrides Sub OnAttached()

AddHandler Me.AssociatedObject.PreviewKeyDown, AddressOf AssociatedObject_KeyDown

End Sub

Protected Overrides Sub OnDetaching()

AddHandler Me.AssociatedObject.PreviewKeyDown, AddressOf AssociatedObject_KeyDown

End Sub

Sub AssociatedObject_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) If ((Keyboard.Modifiers = ModifierKeys.None) AndAlso (e.Key = Me.Key)) Then Dim element = CType(e.OriginalSource, UIElement)

element.MoveFocus(New TraversalRequest(FocusNavigationDirection.Next)) End If End Sub End Class End Namespace Visual C# using System.Windows.Input; using System.Windows.Interactivity; using System.Windows; namespace atmarkit10 {

public class FocusMoveBehavior : Behavior<UIElement> {

public Key Key { get; set; }

protected override void OnAttached() {

this.AssociatedObject.PreviewKeyDown += AssociatedObject_KeyDown; }

(14)

protected override void OnDetaching() {

this.AssociatedObject.PreviewKeyDown -= AssociatedObject_KeyDown; }

void AssociatedObject_KeyDown(object sender, KeyEventArgs e) {

if ((Keyboard.Modifiers == ModifierKeys.None) && (e.Key == this.Key)) {

var element = e.OriginalSource as UIElement;

element.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); } } } } List 2,3: 任意のキーでフォーカス移動するためのビヘイビア 【コラム】インタラクション・トリガーとビヘイビアを利用する際の注意点 インタラクション・トリガーとビヘイビアは、いまのところ.NET Framework の標準ライブラリに は含まれておらず、Expression Blend もしくは Expression Blend SDK のインストールが必須とな る。ただし、関連するクラスの名前空間が System 名前空間の下にあることから、将来的には.NET Framework の標準ライブラリに取り込まれることが期待される。

■ 外観状態管理(VisualStateManager)

Silverlight からの逆輸入品として、もう 1 つ、VisualStateManager クラス(System.Windows 名前空 間)というものがある。直訳すれば、「外観状態の管理者」ということになるが、これは、以下のよう なボタンの例を考えてみると分かりやすいだろう。 ・ユーザーが操作するマウス・ポインタの動きに応じて、MouseOver や Pressed というような状態に なる ・状態ごとに異なる見た目を持つ(例えば、Pressed のときには暗めの色に変化する) ・状態間の遷移の際には0.5 秒程度のアニメーションで滑らかに見た目が変化する このような、ユーザーの操作に応じた状態の変化、状態ごとの見た目、状態間の遷移を管理するための クラスがVisualStateManager クラスである。 WPF 4 では、Button クラスなどの標準コントロールは、マウス・ポインタを重ねれば MouseOver 状 態になるなど、VisualStateManager に最初から対応している。Expression Blend を利用する場合、 Movie 7 に示すように、コントロール・テンプレートを作ると、MouseOver や Pressed などの状態一 覧が表示されるので、見た目の編集が行いやすくなっている。

https://www.youtube.com/watch?v=U6ytKinCyRw&feature=player_embedded

Movie 7: VisualStateManager を使ったコントロール・テンプレートの外観状態の管理の例

(15)

義することもできる。この場合、Expression Blend を使うなら、前述のインタラクション・トリガーと GoToStateAction を利用して状態を遷移させるとよいだろう。 https://www.youtube.com/watch?v=lwmja5LxCTQ&feature=player_embedded Movie 8: 外観状態の定義と GoToStateAction を使った状態遷移の例 今回の解説で使用したサンプル・コードは下記のリンク先からダウンロードできる。 ・第10 回のサンプル・コード(atmarkit09.zip)のダウンロード 次回はタスク・バー統合などのWindows 7 機能や、WPF Toolkit などの追加提供ライブラリについて 説明する。 ■ 第11 回 WPF 連載の落ち穂拾いと、標準以外の WPF 関連パッケージ ■ 連載の最後に、前回までの説明に漏れた、いくつかの機能や、.NET Framework 標準ライブラリ以外の WPF 関連パッケージなどについて説明する。 ■ 落ち穂拾い まず、前回までの説明に漏れたいくつかの機能を簡単に紹介していこう。 スプラッシュ・スクリーン WPF では、アプリケーションのメイン・ウィンドウ表示前に何らかの重たい作業(例えば、大量のプ ラグイン読み込みなど)を行う際に、スプラッシュ・スクリーンを表示できる。 表示方法は簡単で、([プロパティ]ウィンドウで)プロジェクトに追加した画像の[ビルド アクショ ン]プロパティを「SplashScreen」に設定するだけである。Movie 1 に、スプラッシュ・スクリーン表 示の例を示す。 https://www.youtube.com/watch?v=hE8DEWoWU9U&feature=player_embedded Movie 1: スプラッシュ・スクリーンの設定と表示例 この例では、スプラッシュ・スクリーン表示が分かりやすく見えるように、Application クラスの OnStartUp メソッドをオーバーライドして、3 秒間スリープしている。 InkCanvas コントロール

Movie 2 に示すように、XAML コード中に<InkCanvas>要素(System.Windows.Controls 名前空間) を挿入するだけで手書き入力ができる。手書きで入力したストロークは、Strokes プロパティを通して 取り出すことができる。

https://www.youtube.com/watch?v=JPn7spmwc1c&feature=player_embedded Movie 2: InkCanvas 要素を使った手書き入力

(16)

WPF がいかに高機能といえども、過去の資産活用などの理由から、Windows フォームや DirectX との 連携が必要な場合もあるだろう。そのため、以下のように、相互運用のためのクラスが用意されている。 ・Windows フォーム: WindowsFormsHost クラス(System.Windows.Forms.Integration 名前空間)

を用いることで、WPF アプリケーション中に Windows フォームのコントロールを埋め込むことがで きる。

・Win32: WPF は Win32 API で使われる HWND(ウィンドウ・ハンドル)を隠ぺいしているが、場 合によっては(例えば、WPF アプリケーション中で OpenGL を用いたい場合など)HWND が必要 になる。このような場合に用いるのがHwndSource クラス(System.Windows.Interop 名前空間)で、 WPF のウィンドウから HWND を取得できる。

・Direct3D: D3DImage クラス(System.Windows.Interop 名前空間)を用いることで、Direct3D の 描画サーフェスを画像化して、WPF アプリケーション中に埋め込むことができる。

Windows 7

.NET Framework は基本的に、特定の OS に依存しない仕様になっていて、Windows に特に強く依存 する機能はP/Invoke(プラットフォーム呼び出し: ネイティブ・コード相互運用機能)などを介して 行う必要である。

しかし、WPF は“Windows” Presentation Foundation という名前どおり、Windows 上で利用する ことが前提で、Windows 固有の機能もいくつか標準で提供されている(例えば、Microsoft.Win32 とい う、名前どおりWin32 API に依存するクラスを集めた名前空間が、PresentaionFramework アセンブ リに含まれている)。 特にWPF 4 では、Windows 7 の新機能にも対応していて、前回説明したマルチタッチ機能や、ここで 紹介するタスクバー統合機能がその代表例である。 「Windows 7 新時代 第 4 回 Vista から進化した新しいユーザー・インターフェイス」を見れば分か るように、Windows 7 ではタスクバー機能が一新されていて、アプリケーションからタスクバー上のア イコンを操作できるようになった。WPF 4 では、Window クラス(System.Windows 名前空間)に TaskbarItemInfo というプロパティが追加されていて、これを通してタスクバーの操作が行える。 例えば、XAML コード中の<Windows>要素の子として以下のような記述を追加することで、Movie 3 に示すような結果が得られる。 <Window.TaskbarItemInfo> <TaskbarItemInfo Overlay="csharp.ico" ProgressValue="{Binding Progress}" ProgressState="{Binding State}" /> </Window.TaskbarItemInfo> Windows 7 のタスクバーでプログレス表示を行うコード例(XAML) https://www.youtube.com/watch?v=OngJH_DVqDg&feature=player_embedded Movie 3: Windows 7 のタスクバー統合機能を利用する例 ■ Expression Blend 付属品

(17)

Expression Blend には、.NET Framework の標準ライブラリにはない便利な機能がいくつか付属して いる。前回紹介したビヘイビアやトリガーだけでなく、シェイプやビットマップ効果なども追加されて いる。 【コラム】Blend SDK の利用について 前回の繰り返しになるが、視覚的な編集ツールが不要で、Expression Blend 付属のライブラリだけ が必要なら、無償で入手可能Blend SDK をインストールすれば利用可能である。 シェイプ WPF 標準では、四角形やだ円などの基本的な図形しか描画できず、複雑な形状は<Path>要素を利用し て自分で描く必要がある(第9 回参照)。これに対して、Expression Blend では、Figure 1 に示すよう に、矢印、円弧、星形、多角形など、いくつかのシェイプを提供している。

Figure 1: Expression Blend 付属のシェイプ ビットマップ効果(Effect)

(18)

Figure 2: Expression Blend 付属のビットマップ効果 PathListBox コントロール

Expression Blend には、非常に面白いコントロールが 1 つ追加されている。PathListBox コントロー ル(Microsoft.Expression.Controls 名前空間)といって、任意のパス上に子要素を並べるリストボック スである。百聞は一見にしかずということで、動画を見てもらおう。Movie 4 に示すようなアプリケー ションを作成できる。 https://www.youtube.com/watch?v=6lBVjCo2UQ8&feature=player_embedded Movie 4: PathListBox の利用例 ■ マイクロソフトによる追加提供パッケージ

.NET Framework の標準ライブラリや Expression Blend 付属のライブラリ以外にも、いくつかのパッ ケージがマイクロソフトから追加提供されている。その中からいくつか紹介していこう。

NuGet

いくつかのパッケージを紹介する前に、パッケージ管理システムである「NuGet(英語)」というもの を紹介したい。NuGet は以下のような機能を提供している。

・NuGet gallery(英語)上にパッケージを登録/公開する

・NuGet Package Manager(Visual Studio 2010 の拡張機能)を通して、NuGet gallery 上のパッケ ージを参照する

Figure 3 に示すように、Visual Studio 2010 の拡張機能マネージャ(Visual Studio 2010 もしくは Visual Web Developer Express 2010 で利用可能)で、[オンライン ギャラリー]から「NuGet」を検索すれ ば「NuGet Package Manager」が見つかるだろう。まずはこれをインストールしてもらいたい。

(19)

Figure 3: 拡張機能マネージャで NuGet を検索

[ソリューション エクスプローラー]でプロジェクト項目を右クリックすると表示されるコンテキス ト・メニューに[Add Library Package Reference]という項目が追加されていることが分かる。 ここでは例として、第4 回で紹介した WPF Themes を NuGet 経由で利用する例を動画で紹介しよう。 その様子をMovie 5 に示す。

https://www.youtube.com/watch?v=9X76uZgnC6Y&feature=player_embedded

Movie 5: NuGet Package Manager を経由して WPF Themes パッケージを利用する例 CodePlex 2005 年ごろから、.NET Framework への機能追加の方法として、メジャー・バージョン・アップのタ イミングで一斉に追加するのではなく、追加パッケージとして小出しに提供されることが増えてきた。 .NET Framework のメジャー・バージョン・アップは 2~3 年程度の間隔で行われているが、「最長で2 年も待っていられない」という要望が多く、.NET Framework も「小出し」方式を採るようになった。 特に最近では、まだ安定していないバージョンをCodePlex などのサイトで、オープンソースで公開し、 安定したものから製品に取り入れるという方式を取る場合が多い。 WPF も例外ではなく、以下の CodePlex ページで WPF 関連の追加機能が提供されている。 ・CodePlex: Windows Presentation Foundation (WPF)(英語)

このページにはいくつかの成果物が含まれていて、例えば以下のようなものがある。 ○WPF Toolkit

WPF Toolkit では、いくつかの追加のコントロールが提供されている。WPF Toolkit で提供されている コントロールは、安定したものから.NET Framework 本体に取り入れられていて、WPF 4 で追加され

(20)

たDataGrid コントロールや Calendar コントロールも、もともとは WPF Toolkit で提供されていたも のである。

ただし、WPF Toolkit で提供されている追加のコントロールは、Silverlight 向けの同様のプロジェクト であるSilverlight Toolkit と比べると明らかに貧弱である。この問題に対して、Silverlight Toolkit を WPF 向けに移植する「Extended WPF Toolkit」(英語)というプロジェクトがコミュニティ・ベース で進められているので、こちらも参照してみるといいだろう。 ○WPF Ribbon WPF を用いて Ribbon インターフェイスを持つアプリケーションを作成するための「WPF Ribbon」と いうパッケージもCodePlex でプレビュー版が公開されていた。WPF Ribbon はすでに製品版となって おり、以下のURL でダウンロード可能である。

・Microsoft Ribbon for WPF(英語)

WPF Ribbon をインストールすると、ライブラリだけでなく、Visual Studio に Ribbon アプリケーショ ン作成用のテンプレートが追加される。Figure 4 にプロジェクト・テンプレートに沿ってプロジェクト を作成した直後のVisual Studio の様子を示す。

Figure 4: WPF Ribbon プロジェクト・テンプレートにより自動生成された初期の WPF デザインの例 Windows API Code Pack for .NET

.NET Framework の標準ライブラリには、その性質上、汎用性の低い機能や、OS 依存度の高い機能は あまり含まれていない。その結果、Windows の機能をフル活用するためには結局、P/Invoke が必要だ ったり、日本語固有の要求がなかなか満たせなかったりといった問題が生じている。

しかし近年では、このような.NET Framework の標準に漏れる機能も、追加ライブラリという形でマイ クロソフトから提供されるようになった。例えば、Windows 7 固有の機能を利用するための.NET

(21)

Framework 向けライブラリが、Windows 7 のリリースから間を置かずマイクロソフトから公式に提供 されている。

・Windows API Code Pack for Microsoft .NET Framework(英語)

この中には、例えばWPF アプリケーションに Windows エクスプローラのようなファイル参照機能を 追加できる「Windows 7 Explorer Browser Control」などが含まれている。

International Feature Pack

非英語圏に固有の要望に応えるため、マイクロソフトは「International Feature Pack」というものを 公開している。

・Microsoft Visual Studio International Feature Pack 2.0

日本語がらみで WPF に関連するものとしては「YomiganaWPFTextBox」という名前のコントロール が含まれている。これは、Figure 5 に示すように、入力されたテキストの読み仮名を取得できるテキス トボックスである。 Figure 5: YomiganaWPFTextBox コントロールの利用例 この例では、上半分がYomiganaWPFTextBox コントロールになっていて、こちらに日本語(漢字など) を入力すると、その読みが下のテキストボックスに表示される。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 今回の解説で使用したサンプル・コードは下記のリンク先からダウンロードできる。 ・連載:WPF 入門 第 11 回 サンプル 今回をもってWPF 入門も最終回となる。 いまは、シンプルなユーザー・インターフェイスならば HTML ベースで作るべき時代である。このよ うな背景の中、デスクトップ・アプリケーションには操作性や応答性のよい優れたユーザー・インター フェイスが求められている。 この要求にきっちり応えるためには、本連載で説明してきたような、データ・バインディングやMVVM (Model View ViewModel)パターンなどの考え方は必須といっていいだろう。本連載によって、より よいユーザー・インターフェイスを持つアプリケーションが作られることを願う。

Figure 2:  タイムラインの構成と種類
Figure 1:  Expression Blend 付属のシェイプ  ビットマップ効果(Effect)
Figure 2:  Expression Blend 付属のビットマップ効果  PathListBox コントロール
Figure 3:  拡張機能マネージャで NuGet を検索
+2

参照

関連したドキュメント

社内セキュリティ等で「.NET Framework 4.7.2」以上がご利用いただけない場合は、Internet

平成 28 年度については、介助の必要な入居者 3 名が亡くなりました。三人について

森林には、木材資源としてだけでなく、防災機能や水源かん養

* 広告や機能は条件によってはご利用いただけない場合があります。

この点について結果︵法益︶標準説は一致した見解を示している︒

やすらぎ荘が休館(食堂の運営が休止)となり、達成を目前にして年度売上目標までは届かな かった(年度目標

下山にはいり、ABさんの名案でロープでつ ながれた子供たちには笑ってしまいました。つ

大村 その場合に、なぜ成り立たなくなったのか ということ、つまりあの図式でいうと基本的には S1 という 場