更新日: 2010 年 8 月 27 日

C# の内容はこちらに掲載しています。10 行でズバリ!! [C#] マウス イベントの制御

このコンテンツのポイント

  • マウスの右クリックを処理する
  • マウスのホイール操作を処理する
  • マウスの右クリックでコンテキスト メニューを表示する

今回紹介するコード

Visual Basic
Partial Public Class MainPage
    Inherits UserControl

    Public Sub New()
        InitializeComponent()

        AddHandler border1.MouseRightButtonDown, AddressOf border1_MouseRightButtonDown
        AddHandler border1.MouseRightButtonUp, AddressOf border1_MouseRightButtonUp
        AddHandler border2.MouseWheel, AddressOf border2_MouseWheel
        AddHandler canvas1.MouseRightButtonDown, AddressOf canvas1_MouseRightButtonDown
        AddHandler canvas1.MouseRightButtonUp, AddressOf canvas1_MouseRightButtonUp
    End Sub

    Dim LeftButtonDown As Boolean = False

    Private Sub border1_MouseRightButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        e.Handled = True
    End Sub

    Private Sub border1_MouseRightButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        MessageBox.Show("右クリックしました")
    End Sub

    Dim colorValue As Integer = 0

    Private Sub border2_MouseWheel(ByVal sender As Object, ByVal e As MouseWheelEventArgs)
        colorValue = colorValue + (e.Delta / 4)
        If colorValue < 0 Then colorValue = 0
        If colorValue > 255 Then colorValue = 255
        Dim c As Color = Color.FromArgb(255, 255, _
                Convert.ToByte(255 - colorValue), Convert.ToByte(colorValue))
        border2.Background = New SolidColorBrush(c)
    End Sub
End Class
 

目次

  1. はじめに
  2. サンプル アプリケーションの作成準備
  3. ユーザー インターフェイスの作成
  4. マウス イベントを処理する
  5. 右クリックの処理
  6. マウス ホイールの処理
  7. 右クリックでコンテキスト メニューを表示する
  8. おわりに

1. はじめに

Silverlight 4 では、これまで Silverlight のメニューしか使われていなかったマウスの右ボタン クリックにも、独自の機能を割り当てることができるようになりました。また、マウスのホイール操作にも対応しています。

ここでは、簡単なアプリケーションを作成して、マウス イベントを処理するための基本について解説します。

ページのトップへ


2. サンプル アプリケーションの作成準備

まず、Visual Studio を起動して、[ファイル] メニューの [新規作成] から [プロジェクト] をクリックし、[新しいプロジェクト] を開きます。次に、[インストールされたテンプレート] で [Silverlight] カテゴリーにある [Silverlight アプリケーション] を選びます。[名前] には任意のプロジェクト名を指定できますが、ここでは「SampleMouseEvents」とします。

図 1. [新しいプロジェクト] ダイアログで Silverlight アプリケーションのプロジェクトを新規作成

[OK] をクリックすると、[新しい Silverlight アプリケーション] ダイアログが表示され、これから作成する Silverlight アプリケーションが埋め込まれた Web ページを持つ Web サイトを作成するかどうかと、Silverlight のバージョンが確認されます。ここでは、[Silverlight アプリケーションを新しい Web サイトでホストする] のチェックを外します。これで、この Silverlight アプリケーションを実行しようとするたびに、仮の Web サイトが自動作成されます。Silverlight のバージョンは、「Silverlight 4」のままにしておきます。

図 2. [新しい Silverlight アプリケーション] ダイアログ

[OK] ボタンをクリックすると、SampleMouseEvents ソリューションと、Silverlight アプリケーションのための SampleMouseEvents プロジェクトが作成されます。

図 3. プロジェクト作成直後の Visual Studio 2010

ページのトップへ


3. ユーザー インターフェイスの作成

まず、MainPage.xaml に今回のアプリケーションで使うユーザー インターフェイスを作成します。ここでは、Grid を使って領域を四分割し、左上にはファイル名を一覧表示するためのリスト ボックス (ListBox) を、右上にドロップするコントロール (TextBlock) と、その背景となる長方形 (Rectangle) を置きます。下部は 2 つの領域を合わせて、ファイルの内容を表示するための場所 (ScrollViewer) とします。

<UserControl x:Class="SampleMouseEvents.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d"
   d:DesignHeight="300" d:DesignWidth="400">

   <Grid x:Name="LayoutRoot" Background="White">
      <Grid.RowDefinitions>
           <RowDefinition Height="*" />
           <RowDefinition Height="*" />
       </Grid.RowDefinitions>
 
       <Border Grid.Row="0" x:Name="border1" Background="LightCyan">
           <TextBlock Text="右クリックでメッセージ ボックスを表示します。" />
       </Border>
 
       <Border Grid.Row="1" x:Name="border2" Background="LightYellow">
           <TextBlock Text="マウスのホイール操作で色が変わります。" />
       </Border>

   </Grid>
</UserControl>

Visual Studio では、図 4 のように表示されます。

図 4. ユーザー インターフェイスを作成する様子

Note: ここではユーザー インターフェイスを作成するために直接 XAML コードを記述していますが、Visual Studio 2010 では、ツールボックスからデザイナー上にコントロールを配置できます。この場合は、上記で使われているコントロールの名前を使うようにしてください。

ページのトップへ


4. マウス イベントを処理する

マウスの操作に関して、もっともよく使うイベントは Click でしょう。Click は、Button や CheckBox のようにマウスで簡単に操作できるコントロールで使えますが、マウス操作に限定されるわけではありません。たとえば、ボタンに入力フォーカスがあるときにスペース キーを押しても Click イベントは発生します。

Click イベントに関わらず、多くのコントロールには、次のようなマウスに関するイベントが用意されています。

イベント名 イベントが発生するタイミング
MouseLeftButtonDown マウスの左ボタンが押されたとき
MouseLeftButtonUp マウスの左ボタンが離されたとき
MouseMove マウスがコントロール上を移動したとき
MouseRightButtonDown マウスの右ボタンが押されたとき (Silverlight 4 で追加)
MouseRightButtonUp マウスの右ボタンが離されたとき (Silverlight 4 で追加)
MouseWheel マウスのホイールが回転したとき
MouseEnter マウスがコントロールの領域内に入ったとき
MouseLeave マウスがコントロールの領域内から出たとき

このうち、MouseEnter と MouseLeave を除くイベントは「ルーティング イベント」と呼ばれるもので、子コントロールで発生したイベントを親コントロールで処理できます。

また、ボタンの Click イベントがどのように発生しているかを見ると、マウスの左ボタンが "押されたとき" ではなく、"離されたとき" に発生していることがわかります (押し続けることで繰り返し Click が呼び出される RepeatButton コントロールでは、ボタンを押した時点で Click イベントが発生します)。つまり、マウス ボタンが離されたときに処理すれば、Click を処理するのと同じような効果を持ちます。

たとえば、次のようなイベント ハンドラーを記述することで、上部の領域 (border1) をクリックすると「Hello, World!」というメッセージが表示されるようになります。

Partial Public Class MainPage
   Inherits UserControl

   Public Sub New()
       InitializeComponent()

       AddHandler border1.MouseLeftButtonUp, AddressOf border1_MouseLeftButtonUp
   End Sub

   Private Sub border1_MouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
       MessageBox.Show("Hello, World!")
   End Sub

End Class

このプログラムを実行した様子を図 5 に示します。

図 5. MouseLeftButtonUp による処理

ただし、この処理では、下部 (boder2) で左ボタンを押し、ドラッグしたまま上部に移動して離したときでもメッセージが表示されます。上部で押した後、上部で離した場合だけ処理するためには、たとえば次のようにプログラムできます。

Partial Public Class MainPage
   Inherits UserControl

   Public Sub New()
       InitializeComponent()

       AddHandler border1.MouseLeftButtonUp, AddressOf border1_MouseLeftButtonUp
       AddHandler border1.MouseLeftButtonDown, AddressOf border1_MouseLeftButtonDown
   End Sub

   Dim LeftButtonDown As Boolean = False
 
   Private Sub border1_MouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
       LeftButtonDown = True
       border1.CaptureMouse()
   End Sub


   Private Sub border1_MouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
       If LeftButtonDown Then
           LeftButtonDown = False
           border1.ReleaseMouseCapture()
           Dim list = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(border1), border1)
           If list.Count() > 0 Then
               MessageBox.Show("Hello, World")
           End If
       End If

   End Sub
End Class

ここでは、左ボタンが押されたときに、いったんマウスをキャプチャー (特定のコントロールがマウス イベントを捕捉し続けること) し、ボタンが離された時点で、マウスの位置がコントロール内にあるかどうかを調べて、メッセージ ボックスを表示しています。

Note: Click イベントを持つコントロールでは、MouseLeftButtonDown や MouseLeftButtonUp イベントを処理する必要はありません。上記のイベント ハンドラーは、以降のプログラムには反映されていません。

ページのトップへ


5. 右クリックの処理

通常、Silverlight アプリケーション上でマウスの右ボタンをクリックすると、Silverlight 自身に関するコンテキスト メニューが表示されます。Silverlight 3 以前では、この動作は変更できませんでしたが、Silverlight 4 では新たに MouseRightButtonDown、MouseRightButtonUp というマウス イベントが追加され、この動作を変更できるようになりました。

処理手順は左ボタンの場合と同様ですが、右クリックには、あらかじめ Silverlight メニューが割り当てられているため、これを無効にする必要があります。このためには、MouseRightButtonDown イベント ハンドラーで、第 2 引数 (MouseButtonEventArgs 型) の Handled プロパティを true にします。右クリックの実際の動作は、マウス ボタンを離したとき (MouseRightButtonUp イベント) で定義します。たとえば、次のように記述すれば、上部 (border1) で右クリックすることでメッセージ ボックスが表示されます。

   Public Sub New()
       InitializeComponent()

       AddHandler border1.MouseRightButtonDown, AddressOf border1_MouseRightButtonDown
       AddHandler border1.MouseRightButtonUp, AddressOf border1_MouseRightButtonUp

   End Sub

   Private Sub border1_MouseRightButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
       e.Handled = True
   End Sub
 
   Private Sub border1_MouseRightButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
       MessageBox.Show("右クリックされました")
   End Sub

このプログラムを実行した様子を図 6 に示します。

図 6. 上部で右クリックした様子

ページのトップへ


6. マウス ホイールの処理

Silverlight では、MouseWheel イベントを処理することで、マウス ホイールによる操作も処理できます。

次のプログラムは、ホイールを回転することで下部 (boder2) の背景色を変化させるものです。ホイールによる増減は MouseWheel イベント ハンドラーへの第 2 引数 e の Delta プロパティに渡されます。これをもとに colorValue という変数を 0 から 255 の範囲で変化させ、背景色のブラシの色を設定しています。

   Public Sub New()
       InitializeComponent()

       AddHandler border1.MouseRightButtonDown, AddressOf border1_MouseRightButtonDown
       AddHandler border1.MouseRightButtonUp, AddressOf border1_MouseRightButtonUp
       AddHandler border2.MouseWheel, AddressOf border2_MouseWheel
   End Sub
   ……
   Dim colorValue As Integer = 0
 
   Private Sub border2_MouseWheel(ByVal sender As Object, ByVal e As MouseWheelEventArgs)
       colorValue = colorValue + (e.Delta / 4)
       If colorValue < 0 Then colorValue = 0
       If colorValue > 255 Then colorValue = 255
       Dim c As Color = Color.FromArgb(255, 255, _
               Convert.ToByte(255 - colorValue), Convert.ToByte(colorValue))
       border2.Background = New SolidColorBrush(c)
   End Sub

このプログラムを実行した様子を図 7 に示します。なお、アプリケーションが選択されていないときにはホイール イベントが発生しないことがあります。

図 7. 下部でマウス ホイールを回転させた様子

ページのトップへ


7. 右クリックでコンテキスト メニューを表示する

一般的なアプリケーションでは、右クリックすることで、その場に応じたコンテキスト メニューを表示するものが数多くあります。Silverlight には、コンテキスト メニューを表示するためのコントロールは用意されていないので、他のコントロールを組み合わせて実装する必要があります。ここでは、その一例として Popup コントロールを使う例を紹介します。

まず、新しい領域を追加するため、ユーザー インターフェイスを定義する XAML コードを、次のように拡張します。このとき、新たに追加した領域 (canvas1) には、Popup の定義が含まれています。Popup は、プログラム中で一時的にコンテンツを表示したい場合に使うものです。ここでは、リスト ボックス (ListBox) を配置し、その項目として TextBlock を置いて色を表すメニュー テキストを表示しています。

   <Grid x:Name="LayoutRoot" Background="White">
       <Grid.RowDefinitions>
           <RowDefinition Height="*" />
           <RowDefinition Height="*" />
           <RowDefinition Height="*" />
       </Grid.RowDefinitions>

       <Border Grid.Row="0" x:Name="border1" Background="LightCyan">
           <TextBlock Text="右クリックでメッセージ ボックスを表示します。" />
       </Border>

       <Border Grid.Row="1" x:Name="border2" Background="LightYellow">
           <TextBlock Text="マウスのホイール操作で色が変わります。" />
       </Border>

       <Canvas Grid.Row="2" x:Name="canvas1" Background="LightSkyBlue">
           <TextBlock Text="右クリックでメニューを表示します。" />
 
           <Popup x:Name="contextMenu">
               <ListBox>
                   <TextBlock Text="Blue" MouseLeftButtonUp="menu_MouseLeftButtonUp" />
                   <TextBlock Text="Red" MouseLeftButtonUp="menu_MouseLeftButtonUp" />
                   <TextBlock Text="Green" MouseLeftButtonUp="menu_MouseLeftButtonUp" />
                   <TextBlock Text="Yellow" MouseLeftButtonUp="menu_MouseLeftButtonUp" />
               </ListBox>
           </Popup>
       </Canvas>

   </Grid>

イベント ハンドラーは、次のように記述します。

Partial Public Class MainPage
   Inherits UserControl

   Public Sub New()
       InitializeComponent()

       AddHandler border1.MouseRightButtonDown, AddressOf border1_MouseRightButtonDown
       AddHandler border1.MouseRightButtonUp, AddressOf border1_MouseRightButtonUp
       AddHandler border2.MouseWheel, AddressOf border2_MouseWheel
       AddHandler canvas1.MouseRightButtonDown, AddressOf canvas1_MouseRightButtonDown
       AddHandler canvas1.MouseRightButtonUp, AddressOf canvas1_MouseRightButtonUp

   End Sub
   ……
   Private Sub canvas1_MouseRightButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
       e.Handled = True
   End Sub
 
   Private Sub canvas1_MouseRightButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
       Dim pt As Point = e.GetPosition(canvas1)
       contextMenu.SetValue(Canvas.LeftProperty, pt.X)
       contextMenu.SetValue(Canvas.TopProperty, pt.Y)
       contextMenu.IsOpen = True
   End Sub


   Private Sub menu_MouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
       If TypeOf sender Is TextBlock Then
           Dim tblock As TextBlock = CType(sender, TextBlock)
           Dim pinfo As System.Reflection.PropertyInfo _
               = GetType(Colors).GetProperty(CType(tblock.Text, String))
           Dim c As Color
           If pinfo Is Nothing Then c = Colors.Black Else c = pinfo.GetValue(Nothing, Nothing)
           canvas1.Background = New SolidColorBrush(c)
       End If
       contextMenu.IsOpen = False
   End Sub
End Class

前述のケースと同様に、MouseRightButtonDown で e.Handled を true にし、MouseRightButtonUp に右クリックに割り当てたい処理を記述します。ここでは、クリックされた位置をもとに、Popup の位置を設定し、IsOpen プロパティを true にすることでポップアップを表示しています。

menu_MouseLeftButtonUp は、リスト ボックスに配置した TextBlock をクリックしたときに呼び出されるイベント ハンドラーです。ここでは、リフレクションを使ってテキスト文字列から色情報を取り出し、ブラシを生成して、canvas1 の背景色として割り当てています。

このプログラムを実行した様子を図 8 に示します。

図 8. 右クリックでコンテキスト メニューを表示する

ページのトップへ


8. おわりに

Silverlight アプリケーションでは、右クリックやマウス ホイールが使えるので、一般的なアプリケーションと同じようなマウス操作を実装できます。なお、プラットフォームやブラウザーによっては、マウス操作が制限される場合があります。たとえば、Macintosh ではホイール操作はサポートされません。詳しくは「マウス ホイール入力」を参照してください。


Code Recipe Silverlight デベロッパー センター

ページのトップへ