fc2ブログ
 

Technology へようこそ
ここは技術者の「経験」と「ノウハウ」のブログです


2010年12月08日

枠なしウィンドウの作り方

某台湾製萌えキャラ騒ぎをはじめ、次期バージョンの概要も発表され、微妙に盛り上がりつつある Silverlight ですが、実際に利用されているのを見かけるのは相変わらずメディアプレイヤーくらいな気もする今日この頃。

と、それはさておき、今回は最新の「Another TL」で採用した『枠なしウィンドウ(OOB限定)』の実装コードをご紹介。

まぁ、実際にはたいしたことはしておらず、プロジェクトプロパティでOOB設定のウィンドウスタイルを変更したうえで、ウィンドウサイズの変更/移動、マウスカーソルの形状変更くらいをコーディングしてあげれば出来上がりです。
マウスドラッグによるウィンドウ移動やリサイズの実装が1メソッドで実現できるのでえらく簡単です。

・プロジェクトプロパティ - 「ブラウザ外実行の設定」


// ウィンドウサイズ変更/移動
private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (!Application.Current.IsRunningOutOfBrowser) return;

Point pos = e.GetPosition(this);
double borderSize = 8;
Window win = Application.Current.MainWindow;

if (pos.X <= borderSize)
if (pos.Y <= borderSize)
win.DragResize(WindowResizeEdge.TopLeft);
else if (pos.Y >= this.ActualHeight - borderSize)
win.DragResize(WindowResizeEdge.BottomLeft);
else
win.DragResize(WindowResizeEdge.Left);
else if (pos.X >= this.ActualWidth - borderSize)
if (pos.Y <= borderSize)
win.DragResize(WindowResizeEdge.TopRight);
else if (pos.Y >= this.ActualHeight - borderSize)
win.DragResize(WindowResizeEdge.BottomRight);
else
win.DragResize(WindowResizeEdge.Right);
else
if (pos.Y <= borderSize)
win.DragResize(WindowResizeEdge.Top);
else if (pos.Y >= this.ActualHeight - borderSize)
win.DragResize(WindowResizeEdge.Bottom);
else
win.DragMove();
}

// マウスカーソル形状設定
private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
if (!Application.Current.IsRunningOutOfBrowser) return;

Point pos = e.GetPosition(this);
double borderSize = 8;

if (pos.X <= borderSize)
if (pos.Y <= borderSize)
this.Cursor = Cursors.SizeNWSE;
else if (pos.Y >= this.ActualHeight - borderSize)
this.Cursor = Cursors.SizeNESW;
else
this.Cursor = Cursors.SizeWE;
else if (pos.X >= this.ActualWidth - borderSize)
if (pos.Y <= borderSize)
this.Cursor = Cursors.SizeNESW;
else if (pos.Y >= this.ActualHeight - borderSize)
this.Cursor = Cursors.SizeNWSE;
else
this.Cursor = Cursors.SizeWE;
else
if (pos.Y <= borderSize)
this.Cursor = Cursors.SizeNS;
else if (pos.Y >= this.ActualHeight - borderSize)
this.Cursor = Cursors.SizeNS;
else
this.Cursor = Cursors.Arrow;
}

巷では Silverlight/WPF に関して MVVM による実装が注目されているようなので、こうしてイベントをチマチマと書くやり方はいずれ時代遅れになってしまいそうな気配ですが、その辺りは今後の状況を伺いつつ臨機応変に対応していけばよろしいかと。

[ posted by ken ]
スポンサーサイト





2010年10月01日

Silverlightでスカイツリー鑑賞

エラく更新が滞ってしまい、広告が出まくってましたが、
ようやく一息つける状況になってきたので、性懲りも無くSilverlightネタいっときます。

今月の弊社トップページを飾っている東京スカイツリーの写真は、弊社K氏が出勤途中に毎日撮ってきているものなのですが、せっかく毎日撮っているので、自分のほうで容量無制限らしいフォト蔵にアップロードしてたりします。
公開設定にしている枚数もそこそこ貯まってきたので、これをブログネタにすべく、簡単な画像ビューアを作ってみました。

問題だったのは、フォト蔵APIがクロスドメインアクセスを許可していないこと。
SilverlightからのアクセスではAPIが利用できなかったので、こちらのサイトを参考に、PHPで書いた簡易プロキシを経由させてみたところ、無事APIが使えるようになりました。

画面は相変わらずセンスが微妙なところですが、反射っぽい表示と、お約束のアニメーション、フルスクリーン表示対応、簡単なスライドショーあたりを付けてみました。
全部コミコミで所要時間は1日くらいでしたが、やっぱりSilverlightは楽しいですね。



コンパクトデジカメの撮って出し(無加工)なので、天気の悪い日はイマイチですが、天気の良い日はなかなかに良く撮れてます。
自分はデジ一眼使いなのですが(最近あまり撮ってませんが)、いまどきのコンデジもなかなか侮れませんね。

[ posted by ken ]


2010年08月10日

ブラウザ外実行モード(OOB)でのアプリ更新

通常、SilverlightアプリはWebブラウザ上で動作しますので、アプリのバージョンアップは特に意識することなくWebサーバ上に配置したモジュールを入れ替えるだけで事足りるわけですが、ローカルPCにダウンロードしたモジュールを利用する「ブラウザ外実行モード(OOB)」ではどのようにしてバージョンアップすればいいのでしょう?
いたって素朴な疑問ですが、当然ながらそのための仕組みが用意されています。

下記コードをアプリ起動時(Appクラスのコンストラクタ辺りでしょうか)に入れておくだけで、バージョンチェック、および変更されている場合は自動的にダウンロードまで実行してくれます。
チェック+ダウンロードは非同期に行われるため、サンプルでは完了イベントを定義してエラーチェックやメッセージ通知を行っていますが、更新処理そのものは CheckAndDownloadUpdateAsync メソッドを一発呼ぶだけ。

問答無用、確認なしで更新(ダウンロード)されてしまうのはどうかと思いますが、バージョンチェック用のファイルをサーバ上に配置しておくなどすれば、事前にユーザに対して更新通知することもできるでしょうから、更新の仕組み自体はこれで充分かと思われ。
んでも、アセンブリが複数に分割されているような複雑なアプリの場合はどうすればいいんでしょうかね…。
// OOB自動更新
if (App.Current.IsRunningOutOfBrowser)
{
App.Current.CheckAndDownloadUpdateCompleted += (s, arg) =>
{
if (arg.Error == null && arg.UpdateAvailable)
MessageBox.Show("アプリケーションを更新しました。\n" +
"変更を反映するにはアプリケーションを再起動してください。",
"更新通知", MessageBoxButton.OK);
else if (arg.Error != null)
MessageBox.Show("アプリケーション更新でエラーが発生しました。\n" +
"\n[詳細]\n" + arg.Error.Message,
"更新エラー", MessageBoxButton.OK);
};
App.Current.CheckAndDownloadUpdateAsync();
}

[ posted by ken ]


2010年07月28日

ショートカットメニューの表示

Silverlight4でショートカットメニュー(いわゆる右クリックで表示されるメニュー、コントロール名としては ContextMenu)を表示する方法です。(要 Silverlight Toolkit)

XAML上に定義しても結局メニューコマンド実行用のコードは裏に書かざるをえないので、Another TLではコードビハインドで動的にメニューを生成しています。
まぁ、本当はもっとスマートなやり方があるんでしょうけど、変にXAMLとコードが分散するよりは見通し良いかな、と今のところは考えています。見栄えをいじりたければスタイルだけXAML定義しておく、とかすれぱ対応できるかと。

ちなみに、MenuItemのHeaderプロパティに別のコントロールを突っ込めば好き放題にメニューをカスタマイズできますが、ヘンテコUIになる可能性があるのでご注意をw

というわけで、テキストボックスコントロールにコピペ用のメニューを付けるサンプル。
XAMLは端折っちゃいましたが、対象となるTextBoxコントロールにMouseRightButtonDownイベントだけ用意してあげてください。Toolkitの参照設定もお忘れなく。
// コピペ用ショートカットメニューの表示
private void openContextMenu(TextBox txt, double posX, double posY)
{
ContextMenu cm = new ContextMenu();

var miCut = new MenuItem()
{
Header = "切り取り"
};
miCut.Click += (s, e) =>
{
txt.Focus();
Clipboard.SetText(txt.SelectedText);
txt.SelectedText = "";
};
cm.Items.Add(miCut);

var miCopy = new MenuItem()
{
Header = "コピー"
};
miCopy.Click += (s, e) =>
{
txt.Focus();
Clipboard.SetText(txt.SelectedText);
};
cm.Items.Add(miCopy);

var miPaste = new MenuItem()
{
Header = "貼り付け"
};
miPaste.Click += (s, e) =>
{
txt.Focus();
txt.SelectedText = Clipboard.GetText();
};
cm.Items.Add(miPaste);

if (txt.SelectedText == "")
{
miCut.IsEnabled = false;
miCopy.IsEnabled = false;
}

cm.HorizontalOffset = posX;
cm.VerticalOffset = posY;
cm.IsOpen = true;
}

// 利用例
private void TextBox1_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
e.Handled = true;
openContextMenu((TextBox)sender, e.GetPosition(owner).X, e.GetPosition(owner).Y);
}

[ posted by ken ]


2010年03月12日

RIAの今

Silverlight3 が出てからはや8ヶ月。Silverlight4 Beta2 も昨年登場し、
対応するブラウザ、OSも徐々に増えていくなかで、RIAがいまいち盛り上が
りません。Silverlightのホームページでは、

「breakthrough in RIA RIA開発現場の、課題を打ち破る。」
という謳い文句とともにコンテンツの充実が図られ、需要を喚起するような
内容になっています。

我が社も、昨年の5月にSilverlight2を、7月にはSilverlight3によるアプリ
ケーションを作成してデモンストレーションをやっていたりするのですが、

「見栄えはいいね。」

と言ってはくれるものの、そこまでです。もちろん、そこは我が社のアプリ
のせいなのかもしれませんが、景気の先行きが不透明で情報投資できない
というのも理由のひとつなのは間違いないのだと思います。

Silverlightのホームページの言葉に、

「大規模、複数人での開発を、もっと効率的に。」
「画面要件を固めるのは、早いうちに。」
「要件実現可能性の検証も、早期に。」

というのがあります。でも、批判するわけではないのですが、それって、
今まで必ずしもできていなかったことなのか?ということです。そして
実際、Silverlightの開発に触れた者として正直に言うならば、敷居が高い
部分も存在するよ、というのが本音です。

もちろん、多くのベンダーが開発ツールとしてSilverlightの採用をすれば
シェアは広がるのかもしれませんが、エンドユーザに対する喚起を行わない
と、この先、RIAの未来も危ういのではないかと思うのです。
そのためには、やはり開発コストそのものを削減できるようなソリューション
(あるいはツール)とか、エンドユーザに対する情報発信とかはもちろん、
Silverlightの優位性を定性的ではなく、定量的に説明できることが必要で
あると考えています。

[ posted by H.K ]


2009年11月28日

Silverlight - 開発ツール

Silverlightアプリケーションを開発する為に必要なソフトを取り上げてみました。
(各バージョンは執筆時点のものです。)

◆Visual Studio 2008 SP1◆
各エディションの紹介
◎Team System
 複数の開発者で構成されるプロジェクトチームを想定したバージョンであり、Visual Studioの最上位のものです。基本機能すべてに加えて、プロジェクト管理関連のツールが含まれているそうです。
◎Professional Edition
 主に小規模の開発プロジェクト想定しており、小~中規模のアプリケーション開発には必要十分な機能を備えているといえます。
◎Standard Edition
 個人プログラマを対象にした構成のようです。決してアプリケーション開発に不十分というわけではなさそうです。
◎Express Edition
 評価、学習用の無償エディションであり、開発されたプログラムは業務で使用することはできません。

Silverlightのアプリケーション開発を行うならば、Professional Editionを選択すべきです。
Microsoftのダウンロードサイトで評価版が提供されています。

SP1の導入時の注意
インストールを開始する前に、Machine Debug Managerサービスを停止する必要があります。

◆Microsoft Silverlight Tools◆
Microsoftのダウンロードサイトにて提供されているToolになります。
Visual Studioをインストールした後で導入して下さい。

◆Expression Studio 3◆
Expression Studio 3に含まれている、Expression Blend 3を導入し、Silverlightアプリケーションのユーザーインターフェイスをデザインすることができます。

Expression Blend 2を使用する場合は、ServicePackを適用して下さい。

[ posted by h.i ]


2009年10月02日

Silverlight - 既存のWEBアプリと比較

今回は、既存のWEBアプリケーションについて基本をおさらいしてみました。
その上で、Silverlightの特徴を記述します。

まずは、
HTTPの処理方式について
 ClientがブラウザでWebサイトのコンテンツを表示する場合、HTTPリクエストという形式でWebServerに対して『コンテンツを構成するHTMLファイルや画像ファイルを下さい。』と依頼します。するとWebServerは要求されたファイルを返します。

 Clientのブラウザは受け取ったHTMLファイルを解析してコンテンツを表示します。この時、WebServerはファイル送信後に、そのClientの情報(アドレス等)を破棄してしまいます。
 WebServerはその都度、Clientからの依頼に対して応答を返しますが、依頼元の情報は記憶していない為、とても単純な仕組みが実装でき、コンテンツを効率よく表示しているのです。
※このように、Clientの情報をWebSeverは記憶せず、パフォーマンスの向上と記憶容量の節約する事を、【ステートレス(Clientのステート:状態を保持しないこと)】と、呼ぶそうです。

次に、
HTMLページの移動・更新について
 上述した通り、シンプルなやりとりでブラウザがWebページを表示するのですが、ハイパーリンクをクリックしてページを移動する度に毎回WebServerへのHTTP要求が送信され、ブラウザは返されたHTMLファイルを解析して表示しています。
 このように、HTTPとHTMLによるWebコンテンツの閲覧では、ページの移動や更新を行う際に、毎回WebServerへアクセスが発生します。
※高速化のために、一度表示したページを保存しておいて、次回以降に再利用する「Webキャッシュ」や「インターネット一時ファイル」と呼ばれる方式が一般的には利用されています。

ここで、
HTMLによる大量データ表示について
 一般的に、HTMLはWeb上のDocumentを記述する為に使用されているマークアップ言語です。マークアップとは、タグによりText文書の見た目や構造を指定することを意味します。タグとはHTMLの場合<>で囲まれた指定文字を意味します。

 HTMLによるページでは、画像の読み込みやハイパーテキストによる別文書へのリンクを容易に行えますが、基本的にはテキスト文書にマークアップやCSSスタイルを設定したり、表組機能を利用してページを格子スタイルでレイアウトすることしかできません。

 例えば、業務アプリによく見られる「スクロールバー付のデータグリッドで大量のデータを一度に表示する」というような画面を作成することはできず、検索エンジンの結果画面のように「次の○○件」や「前の○○件」というリンクをたどってページを切り替えるか、縦に長いページで表示するしかありません。

 ページの切り替えを行う度に、WebServer上のプログラムにアクセスすることになり、レスポンス対策だけで、かなりのインフラコストを投資する必要がありました。

最後に
CGI/PHP/JSP/JavaサーブレットによるWebアプリについて
 PerlによるCGIや、PHP、JSP、Javaサーブレットなどで作成されたWebアプリは、通常HTMLベースの画面構成となる為、WebServerへのHTTP要求がClientから送られる時に、プログラムが実行され、結果をHTMLドキュメントとして要求元に返すという仕組みになります。

 これらのWebアプリでは、ページを切り替える度に以下の処理が実行されています。
 Ⅰ.WebSeverへの処理要求を送る。
 Ⅱ.WebServer上で、プログラムが実行され、結果をHTMLドキュメントで返す。
 Ⅲ.Clientのブラウザが返されたHTMLドキュメントを解析してページ全体を更新する。

※HTTP通信はステートレスなので、ショッピングカートのような処理を実現する為には、ブラウザが生成する「Cookie」を保持することで、Clientの識別を行う必要があります。


◆SilverlightによるWebアプリケーション◆
 SilverlightによるWebアプリでは、以下のような特徴でHTMLベースのアプリケーションにおける不利な点を改善することができるそうです。
 WebServerにアクセスしなくてもページを切り替えることが可能。
 ページ全体を切り替えなくても、データを取得して表示することができる。

 つまり、WebServerにアクセスする回数が少なくなり、レスポンスが向上します。また、デザインやユーザーインターフェースの優位な点として、
 Windows Presentation Foundation (WPF)テクノロジーを使用する為、グラフィカルな表現やアニメーション効果を追加することができ、デザイン面や操作性が向上する。
ということが挙げられるそうです。

WPFについては、今後もう少し勉強してこのブログ内で記述したいと考えています。

[ posted by h.i ]


2009年09月04日

Silverlight3でマウスホイールスクロール

SilverlightのDataGridやListBoxなどのScrollableなコントロールは標準ではホイールスクロールに対応していません。
Silverlight3ではMouseWheelイベントが追加されたということなので、マウスホイールによるスクロール実装が簡単にできるようになったのかと思いきや、実際にやってみるとこれがなかなかうまくいきません。

将来的にはBlend3でBehaviorを設定するだけで簡単に実現できるようになりそうな雰囲気ですが、Blend3もベータ版の状態だし、現状ではホイールスクロール用のBehavior自体も提供されていない様子。

というわけで、海外サイトを中心に徘徊した挙句、書いてみたコードを晒しておきます。
(主に参考とさせていただいたのはこちら)
Imports System.Windows.Automation.Peers
Imports System.Windows.Automation.Provider

Private Sub LayoutRoot_MouseWheel(ByVal sender As Object, _
ByVal e As System.Windows.Input.MouseWheelEventArgs) Handles LayoutRoot.MouseWheel

For Each el In VisualTreeHelper.FindElementsInHostCoordinates( _
e.GetPosition(Nothing), CType(sender, FrameworkElement))
Dim peer = FrameworkElementAutomationPeer.FromElement(el)
If peer Is Nothing Then
peer = FrameworkElementAutomationPeer.CreatePeerForElement(el)
End If
If peer IsNot Nothing Then
Dim scroll As IScrollProvider = _
CType(peer.GetPattern(PatternInterface.Scroll), IScrollProvider)
If scroll IsNot Nothing Then
If scroll.VerticallyScrollable Then
If e.Delta < 0 Then
scroll.Scroll(Automation.ScrollAmount.NoAmount, _
Automation.ScrollAmount.SmallIncrement)
ElseIf e.Delta > 0 Then
scroll.Scroll(Automation.ScrollAmount.NoAmount, _
Automation.ScrollAmount.SmallDecrement)
End If
Exit For
End If
End If
End If
Next

End Sub
コイツを丸々コピペするだけで、Scrollableなコントロールがホイールスクロール対応になるはず。(バグがあったらすみません)

通常、SLの画面(UserControl)のルートエレメントとして定義することになるであろう「LayoutRoot」グリッドのMouseWheelイベント内で、現在のマウスポインタがあるポジションのエレメントを取得し、それがスクロール可能なエレメントであった場合、ホイールの回転に従って上下にスクロールさせる仕組みです。

まぁ、こんなコードはいずれ不要になってくれることを希望するわけですが…。

[ posted by ken ]


2009年08月30日

イベント定義の落とし穴

Silverlightを使って社内システム開発プロジェクトをやっています。
知っている方も多いと思われますが、Silverlight/WPFでは、UI(画面)の定義に
XAML(ザムル)というXMLベースの拡張言語を使います。(FlexではMXMLでしたか?)

個人的な感想をいうと、はじめは取っ付きにくいのですが、触りはじめて2ヶ月
たった今でも正直言って少々(いや、かなり?)違和感があります。

VBではお馴染みの"Click"や"SelectionChanged"などのイベントを定義すると、
インテリセンス機能(VS2008の定義画面で)で、イベントハンドラを選択する
ことができます。"新規"を選択すると、メソッドの空枠を作ってくれたりします。
この場合、イベントハンドラには Handles 句が付きません。

もちろん、今までどおり、VS2008のエディタでイベントハンドラを作成すること
もできるのですが、この場合は Handles 句が付きます。

どちらで定義すべきなのか?という問題は確かにあるのですが・・・。

ある機能を作成、コーディングもひととおり終わり、テスト中。

デバッグ実行をしていると、とあるイベントハンドラが2回呼ばれます。はれ?
おかしいなあ。どうして2回来るの?ああ、ここで・・・いや?ちがうなー。

SilverlightはWebサービスを使用するので、DBとの通信を行う際には非同期に
なります。それはわかっているのですが、どうして特定のイベントハンドラが
2回呼ばれるのかがわかりません。

勘のいい方、もうおわかりですね?

そう、XAMLとエディタの両方でイベントハンドラ定義を行っていたのです。

ちなみに両方で定義した場合、XAML定義のほうが優先(先に)呼ばれるようです。

[ posted by H.K ]


2009年08月15日

Silverlightに興味をもって

弊社では現在、Microsoft の Silverlight を使用したアプリケーション開発に力を入れています。
残念ながら、私は社内の【Silverlight製の業務アプリデモ】作成プロジェクトには参加できなかったので、[ken]さんや[H.K]さんのような知識も経験も無く、Silverlightについては素人同然です。

そこで、私も個人的にSilverlightについて勉強を始めようと思いました。このブログにも今後、継続して記事を書いていければと考えています。
(既出の記事に比べると、幾分物足りないと思いますがご容赦下さい。)

まずは、Silverlightの特徴を記述します。

SilverlightはRIA(Rich Interactive Applications)と呼ばれるカテゴリに属するインフラのようです。
この分野には既にAdobe Systems社による[Flash]、[Flex]、[AIR]といったインフラがありましたが、Microsoftが参入した形となりました。
RIAという概念は、Adobe Systems社と合併する前の Macromedia社が提唱した、Flash技術をベースとした高機能なWeb Applicationを意味するもので、元々は Rich Internet Applications の略だったそうです。これをMicrosoftが Rich Interactive Applications と再定義したようです。

RIAといいますか、Silverlightのメリットを5つ紹介します。

1.高度なユーザエクスペリエンス(UX)
多彩なグラフィックスで構成されており、高品質のビデオ配信をサポートしているので、
機能が豊富でユーザにとっても使い安いアプリケーションとなります。

2.広範囲で使用できる
Web Applicationなので、インターネット環境を利用することができます。そして、ユーザは接続できる環境と、ブラウザがあれば広い範囲でアプリケーションを使用することができます。

3.インストールをしなくてよい
ブラウザ上で動作することから、インストールプログラムによるインストールや個別のバージョンアップは必要ありません。ブラウザとネットワークのメンテナンスのみが必要になります。
ただし、アプリケーションを初めて使用する際、ブラウザにSilverlightのプラグインを導入する必要があります。

4.コンテンツと表現力の充実
Silverlightは、Windows Presentation Foundation(WPF)テクノロジに基づいており、WPFが持つグラフィックス、アニメーション、メディア、その他のクライアント機能により、ブラウザベースのWeb Application のユーザインタフェースが大幅に拡張されます。

5.パフォーマンスがよい
クライアント側でアプリケーションの処理を行い、Page移動もサーバーへアクセスしなくても行える為、ネットワーク負荷やサーバー負荷を抑えることができます。その為、HTMLベースのアプリケーションと比較しても、かなりパフォーマンスが向上します。

なかなか魅力的なアプリケーションが開発できそうですね。もちろん既出の記事にもありますように問題点をいくつか解決する必要があるようです。
[ posted by h.i ]