マウス・ホイールと、通知領域への表示
マウス・ホイールによるスクロールと拡大・縮小を実装する
第2回では、マウス操作のMouseRightButtonDownイベントを、また、第3回では、ブラウザ外実行について述べました。今回は、マウス操作とブラウザ外実行を使った2つのサンプルを紹介します。
要点のみ解説していきますので、ツールの操作手順や開発の基本的な手順については、これまでの連載を参照してください。開発言語はVisual Basicです。
まず、Silverlight 4でサポートされた、マウス・ホイールによるサンプルからです。図1のように、画像を拡大・縮小させたり、TextBox内に表示されているデータをスクロールさせてみましょう。
サンプル・ファイルはこちらからダウンロードできます。
図1: マウス・ホイールの動きに連れて、テキストがスクロールしたり、画像が拡大・縮小する |
VS 2010のメニューから[File/New/Project]を選択します。「Silverlight Application」を選択して、「Name」に任意のプロジェクト名(サンプルでは「SL4_MouseWheel」)を指定します。.NET Frameworkのバージョンや「Silverlight Version」もデフォルトのままで[OK]ボタンをクリックします。
Solution Explorerのプロジェクト名を右クリックして「Project Dependencies(プロジェクト依存関係)」を選択し、「Project Dependencies」ダイアログ・ボックスの「Depends on(依存先)」内のチェック・ボックスにチェックを付けておきます。
ここで、Solution Explorer(ソリューション・エクスプローラ)からXML文書ファイル(リスト1)を追加します。また、Imageフォルダを作成して、サンプル画像ファイルも追加しておきます。ダウンロード用ファイルには、XML文書ファイル(WhatsLinq.xml)と画像ファイル(LinqSampleImage.png)は追加済みです。
XMLデータは、LINQ to XMLで処理しますので、「Project/Add Reference」からSystem.Xml.Linqを追加してください。一度使用したコンポーネントは、「Recent」タブ内から指定するとよいでしょう。
リスト1: TextBoxコントロールに表示させるデータを記録したXML文書ファイル(WhatsLinq.xml)
XML設計の心得タイトル>
XMLデータの処理には、LINQ to XML(Language-Integrated Query,統合言語クエリー)を用いる。
LINQは、.NET Framework3.5より追加された、言語埋め込み型クエリー技術である。2008年12月に日本語版がリリースされたVisual Studio 2008から利用可能となっている。LINQクエリーの基本パターンは、RDB(LINQ to SQL)、XML(LINQ to XML)、Object(LINQ to Object)を問わず同一であるため、データ形式別に異なるクエリー言語を習得する必要はない。~後略~
節>
章>
書籍>
ツール・ボックスからコントロールをレイアウトする前に、XAMLコードを編集しておきます。このサンプルでは、TextBoxをスクロールする際に、Canvas.Topの値が必要になりますから、XAMLコード中の
UserControlのPropertiesペインの[Layout]を展開して、Widthに800、Heightに600を指定します。
タイトル表示用のTextBlockコントロール、画像表示用のImageコントロール、XML文書中のテキストを表示するTextBoxコントロールを、1個ずつレイアウトします。
ImageプロパティのWidthは300、Heightは350とし、SourceプロパティにはImageフォルダ内の画像を指定します。
TextBoxコントロールのPropertiesの「Other」を展開して表示されるAcceptsReturnプロパティにチェックを付け、改行を許可して表示するように設定します。VerticalScrollBarVisibilityプロパティにはAutoを指定し、データがTextBoxの表示範囲を超える場合は垂直スクロール・バーを表示します。テキストは回り込んで表示されるよう、「Text」を展開して表示されるTextWrappingプロパティにWrapを指定しておきます。
すべてレイアウトすると、図2のようになります。このレイアウトの結果として書きだされるXAMLコードは省略します。
図2: TextBlock、Image、TextBoxコントロールをレイアウトした |
マウス・ホイールによる処理を記述する
レイアウトができたら、MainPage.xamlを展開してMainPage.xaml.vbを開き、リスト2のようなロジック・コードを記述します。
リスト2: マウス・ホイールによる処理を記述したロジック・コード(MainPage.xaml.vb)
■名前空間の読み込みと変数の宣言
Option Strict On
LINQ to XMLでXMLを処理するクラスの含まれるSystem.Xml.Linq名前空間をインポートします。
Imports System.Xml.Linq
Double型のメンバ変数_topを宣言します。この変数には、TextBox1コントロールのCanvas.Topの値が格納されます。
Dim _top As Double
■ページが読み込まれたときの処理
GetValueメソッドでTextBox1コントロールのCanvas.Topの値を取得し、変数_topに格納しておきます。
XElement.LoadメソッドでXML文書ファイルを読み込みます。LINQ to XMLを用いて要素の内容テキストを取得して、TextBox1コントロールに表示します。
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
_top = CDbl(TextBox1.GetValue(Canvas.TopProperty))
Dim xmldoc As XElement = XElement.Load("WilliamBlake.xml")
Dim contentStr = xmldoc.Descendants("情報")..Value
TextBox1.Text = contentStr
End Sub
■マウス・ポインタがImage1コントロール上にあって、マウス・ホイールを回転させたときに発生するイベント
e.Deltaプロパティで、マウス・ホイールの相対的な変化量を取得します。
その値が0より大きい場合は、Image1コントロールのWidthとHeightの値を10ずつ減少させ、画像を縮小します。画像の最小サイズは幅100とし、Widthの値が100以下になったときは、処理を中止します。
マウス・ホイールの変化量が、0より小さかった場合は、Image1コントロールのWidthとHeightの値を10ずつ増加させ、画像を拡大します。画像の最大のWidthは500とし、これを超える時は処理を中止します。
Private Sub Image1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Input.MouseWheelEventArgs) Handles Image1.MouseWheel
If e.Delta > 0 Then
If Image1.Width
Image1.Width = 100
Exit Sub
End If
Image1.Width -= 10
Image1.Height -= 10
Else
If Image1.Width >= 500 Then
Image1.Width = 500
Exit Sub
End If
Image1.Width += 10
Image1.Height += 10
End If
End Sub
■マウス・ポインタがTextBox1コントロール上にあって、マウス・ホイールを回転させたときに発生するイベント
画像の場合と同様に、e.Deltaプロパティでマウス・ホイールの相対的な変化量を取得します。
その値が0より大きい場合は、上向きにスクロールさせます。GetTopメソッドで、TextBox1コントロール内のTopの値を取得して、1ずつ減少させた値をSetTopメソッドで設定します。
変化した値が0より小さい場合は、下向きにスクロールさせます。1ずつ加算した値をSetTopメソッドで設定します。
スクロールによってTextBoxそのものがスクロールすることを防ぐため、TextBoxの上マージンは、「_top」で取得したCanvas.Topの値を維持します。
Private Sub TextBox1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Input.MouseWheelEventArgs) Handles TextBox1.MouseWheel
If e.Delta > 0 Then
Canvas.SetTop(TextBox1, Canvas.GetTop(TextBox1) - 1)
Else
Canvas.SetTop(TextBox1, Canvas.GetTop(TextBox1) + 1)
End If
Canvas.SetTop(TextBox1, _top)
End Sub