マウス・ホイールと、通知領域への表示

2010年6月10日(木)
PROJECT KySS

マウス・ホイールによるスクロールと拡大・縮小を実装する

第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

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています