掲示板お問い合わせランダムジャンプ



この広告は30日以上更新がないブログに表示されております。 新しい記事を書くことで広告を消すことができます。

Top Index

2009年01月25日
Silverlight2でMDIアプリケーションを作る
開発環境:Visual Studio 2008 Standard Edition

参考:Silverlight公式サイト
  チュートリアル1:コントロール
  チュートリアル3:スタイルとテンプレート

Silverlightアプリケーションは、Windowsフォームアプリケーションとは作り方がかなり異なり、特に画面遷移などは特殊です。
画面遷移が特殊ということもあってか、MDI(マルチ・ドキュメント・インタフェース)アプリケーションの作成方法などは見当たりません。

ということで、MDIアプリケーションが作れるかどうかを試してみました。

silverlight_mdi_sample

動作テストサイトもご参考ください。
公式サイトでは、PageSwitcherと呼ばれる中身の無いページが画面遷移を管理する手法がとられていますが、この手法は1画面しか表示できないので、これに手を加えることとします。

実現化には試行錯誤がありましたので、主だった課題と解決策だけ記載します。


1.親ウインドウ内に子ウインドウを表示する

最初は親ウインドウに子ウインドウ表示用のキャンバスを設置して、そこに子ウインドウを表示させる方法を思いつく。
しかし、キャンバスで処理した場合、Windows.VerticalAlignment.Stretch が機能せず、子ウインドウの最大化処理がなかなかうまくいかない。
次に、親ウインドウにあるGridの指定セルへの代入を思いつく。
Gridのセル座標プロパティへの代入方法に戸惑うも

  Window.SetValue(Grid.RowProperty, 1)

と記載することで解決。
これにより、子ウインドウの最大化、最小化が再現できた。


2.子ウインドウをドラッグ移動させる

冒頭に紹介したチュートリアルに、ボタンコントロールのドラッグ処理があるので、参考にする。
ただし、チュートリアルでは親コントロールがキャンバスであるため、

  fe.SetValue(Canvas.LeftProperty, 1)

という記述はできない。
Leftプロパティの代わりとなるものとしてMarginプロパティを思いついたので、マージンでドラッグ制御することにする。
座標処理がややこしいものの、割と簡単に再現できた。


3.子ウインドウをリサイズする

基本は「2」と同じなのだが、ドラッグ開始地点がない。
このため、リサイズ用の極小セル(3ピクセル)を用意し、Rectangleを配置。
同RectangleのMouseLeftButtonDownイベントでドラッグを検知するようにした。

これで終わりかと思ったが、子ウインドウのHeight、Widthプロパティが取得できない場合があることが発覚。(値を初期化していない場合、-1.#IND が返されることがある)
もし、正しい数値が取得できない場合は、 ActualWidthプロパティ を利用することで回避。

ウインドウのフレームの選択がしづらい、反応が悪い、アイコンが変わらない(アイコンファイルを用意する必要がある)など不満点もなくはないが、とりあえずよしとする。


4.子ウインドウの最前面化

Zオーダーのプロパティはないので代案を考える。
グリッドの場合、最後に追加した子ウインドウが最前面表示されるので、インデックスを変更することで対応する。

これで終わりかと思ったが、最前面化を開始するイベントの取得が一筋縄でいかない。
子ウインドウがフォーカスしたときに、最前面化すればよいと思ったが、RoutedEven(「イベントは上位のコンテナに伝播していく」という仕様。下位のコントロールでイベントをフックしてしまうと、上位へはイベント自体が発生しなくなる。)により、最小化、最大化ボタンなどがイベントをフックしなくなった。

全部のコントロールにフォーカスイベント時に「最前面化する」などという処理を書くのは現実的ではないので、フォーカス処理をするためだけに子ウインドウを全体を覆う、マスク用のコントロールを配置。
子ウインドウがフォーカスを失った場合に表示させ、マスクコントロール以外のイベントが発生しないように抑止。
マスクコントロールクリック時、マスクコントロールを非表示にし、子ウインドウを最前面化することで再現可能となった。

通常のウインドウアプリケーションと比べて、フォーカス移す作業が1つ増えるが、よしとする。


以上です。

まだ、改良の余地はありますが、最低限の動作ができるので公開します。

(今のところの改良点
( 最小化アイコンの整列(StackPanelを使う?)や、
( リサイズの上限指定、
( 子ウインドウ操作(全最小化、整列、任意選択)

今回より、ソースコードもダウンロードできるようにしましたので、よろしければどうぞ。

ソース:http://dotnet.sakura.ne.jp/Tips/Silverlight2/EmulateMDI/SilverlightMdiApplication_src.zip


余談
Wikiには「MicrosoftはMDI形式のアプリケーションを推奨しておらず・・・」と記載があった^^;。
ビジネスアプリケーションにおいていえば、複数の情報を元に情報処理を行うにはSDIよりMDIのほうが向いていると思うんですけどねぇ。SDIであれば並べて表示ということすらできませんし。
(SDIでの解決方法は、アプリケーションを複数起動することだと思いますが、ビジネスアプリケーションを複数起動するっていうのもちょっとアレかと)
[ 投稿者:mk3008 at 18:04 | Silverlight | コメント(0) | トラックバック(0) ]

この記事へのコメント

この記事へのトラックバック

この記事へのトラックバックURL
http://shinshu.fm/MHz/88.44/a12153/0000268891.trackback

この記事の固定URL
http://shinshu.fm/MHz/88.44/archives/0000268891.html

記事へのコメント
 
簡単演算認証: 9 x 4 + 5 =
計算の答えを半角英数字で入力して下さい。
名前: [必須]
URL/Email:
タイトル:
コメント:
※記事・コメントなどの削除要請はこちら