<a href="http://webabcd.blog.51cto.com/1787395/342790" target="_blank">[索引頁]</a>
<a href="http://down.51cto.com/data/100302" target="_blank">[源碼下載下傳]</a>
穩紮穩打Silverlight(13) - 2.0互動之滑鼠事件和鍵盤事件
介紹
Silverlight 2.0 人機互動:響應使用者的滑鼠操作和鍵盤操作
MouseEnter - 滑鼠進入時觸發的事件(顯然,此事件不能冒泡)
MouseLeave - 滑鼠離開時觸發的事件(顯然,此事件不能冒泡)
MouseLeftButtonDown - 滑鼠左鍵單擊按下時觸發的事件
MouseLeftButtonUp - 滑鼠左鍵單擊按下并放開時觸發的事件
MouseMove - 滑鼠移動時觸發的事件
MouseEventArgs.GetPosition() - 滑鼠相對于指定元素的坐标
MouseButtonEventArgs.Handled - 此事件是否已被處理
KeyDown - 滑鼠按下時觸發的事件
KeyUp - 滑鼠按下并放開時觸發的事件
KeyEventArgs.Key - 與事件相關的鍵盤的按鍵 [System.Windows.Input.Key枚舉]
KeyEventArgs.Handled - 是否處理過此事件
System.Windows.Input.Keyboard.Modifiers - 目前按下的輔助鍵 [System.Windows.Input.ModifierKeys枚舉]
線上DEMO
示例
1、Mouse.xaml
<UserControl x:Class="Silverlight20.Interactive.Mouse"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--路由事件是一種可以針對元素樹中的多個偵聽器(而不是僅針對引發該事件的對象)調用處理程式的事件-->
<!--
MouseLeftButtonDown, MouseLeftButtonUp和MouseMove均為向上冒泡的路由事件
本例的事件路由為:Ellipse -> StackPanel -> UserControl 或 Rectangle -> Canvas -> StackPanel -> UserControl
如果不想向上冒泡,則可以使用 MouseButtonEventArgs.Handled = true 告知事件已被處理
-->
<StackPanel HorizontalAlignment="Left" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown" >
<!--
MouseEnter - 滑鼠進入時觸發的事件(顯然,此事件不能冒泡)
MouseLeave - 滑鼠離開時觸發的事件(顯然,此事件不能冒泡)
MouseLeftButtonDown - 滑鼠左鍵單擊按下時觸發的事件
MouseLeftButtonUp - 滑鼠左鍵單擊按下并放開時觸發的事件
MouseMove - 滑鼠移動時觸發的事件
-->
<Ellipse x:Name="ellipse" Width="200" Height="100" Fill="Red" Margin="5"
MouseEnter="ellipse_MouseEnter"
MouseLeave="ellipse_MouseLeave"
MouseLeftButtonDown="ellipse_MouseLeftButtonDown"
MouseLeftButtonUp="ellipse_MouseLeftButtonUp"
>
</Ellipse>
<Canvas Margin="5">
<!--用于示範拖放的矩形-->
<Rectangle x:Name="rectangle" Fill="Blue" Width="50" Height="50"
MouseLeftButtonDown="rectangle_MouseLeftButtonDown"
MouseLeftButtonUp="rectangle_MouseLeftButtonUp"
MouseMove="rectangle_MouseMove"
/>
</Canvas>
</StackPanel>
</UserControl>
Mouse.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Silverlight20.Interactive
{
public partial class Mouse : UserControl
{
public Mouse()
{
InitializeComponent();
}
void ellipse_MouseEnter(object sender, MouseEventArgs e)
ellipse.Fill = new SolidColorBrush(Colors.Yellow);
void ellipse_MouseLeave(object sender, MouseEventArgs e)
ellipse.Fill = new SolidColorBrush(Colors.Red);
private void ellipse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
private void ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
ellipse.Fill = new SolidColorBrush(Colors.Blue);
// MouseButtonEventArgs.Handled - 此事件是否已被處理
// false - 未被處理,事件的路由為向上冒泡
// true - 已被處理,事件的路由為不再冒泡
e.Handled = true;
private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
// 如果滑鼠單擊 rectangle 對象,則 會 執行到此句
// 如果滑鼠單擊 ellipse 對象,則 不會 執行到此句,因為之前 ellipse 對象的 MouseLeftButtonDown 事件中已經設定 e.Handled = true ,是以事件不會冒泡至此
ellipse.Fill = new SolidColorBrush(Colors.Black);
// 是否正在捕獲滑鼠
private bool _isMouseCaptured;
// 滑鼠垂直方向上的坐标
private double _mouseY;
// 滑鼠水準方向上的坐标
private double _mouseX;
private void rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
// MouseButtonEventArgs.GetPosition() - 滑鼠相對于指定元素的坐标
_mouseY = e.GetPosition(null).Y;
_mouseX = e.GetPosition(null).X;
// CaptureMouse() - 在指定的元素上捕獲滑鼠
rectangle.CaptureMouse();
_isMouseCaptured = true;
public void rectangle_MouseMove(object sender, MouseEventArgs e)
if (_isMouseCaptured)
{
// 移動前和移動後的滑鼠 垂直方向 和 水準方向 的位置的內插補點
double v = e.GetPosition(null).Y - _mouseY;
double h = e.GetPosition(null).X - _mouseX;
// 移動後的 rectangle 對象相對于 Canvas 的坐标
double newTop = v + (double)rectangle.GetValue(Canvas.TopProperty);
double newLeft = h + (double)rectangle.GetValue(Canvas.LeftProperty);
// 設定 rectangle 對象的位置為新的坐标.
rectangle.SetValue(Canvas.TopProperty, newTop);
rectangle.SetValue(Canvas.LeftProperty, newLeft);
// 更新滑鼠的目前坐标
_mouseY = e.GetPosition(null).Y;
_mouseX = e.GetPosition(null).X;
}
private void rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
// ReleaseMouseCapture() - 如果指定的元素具有滑鼠捕獲,則釋放該捕獲
rectangle.ReleaseMouseCapture();
_isMouseCaptured = false;
}
}
2、Keyboard.xaml
<!--
KeyDown - 滑鼠按下時觸發的事件
KeyUp - 滑鼠按下并放開時觸發的事件
-->
KeyDown和KeyUp均為向上冒泡的路由事件,本例的事件路由為:TextBox -> Canvas -> UserControl
<UserControl x:Class="Silverlight20.Interactive.Keyboard"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="userControl"
KeyDown="userControl_KeyDown">
<Canvas>
<TextBox x:Name="textBox" Text="TextBox" />
</Canvas>
Keyboard.xaml.cs
public partial class Keyboard : UserControl
public Keyboard()
this.Loaded += new RoutedEventHandler(Keyboard_Loaded);
// 為 UserControl 注冊 KeyUp 事件
userControl.KeyUp += new KeyEventHandler(userControl_KeyUp);
void Keyboard_Loaded(object sender, RoutedEventArgs e)
// 讓 UserControl 獲得焦點,這樣該 UserControl 内的元素才能監聽到鍵盤事件
userControl.Focus();
private void userControl_KeyDown(object sender, KeyEventArgs e)
// 擷取 textBox 對象的相對于 Canvas 的 x坐标 和 y坐标
double x = (double)textBox.GetValue(Canvas.LeftProperty);
double y = (double)textBox.GetValue(Canvas.TopProperty);
// KeyEventArgs.Key - 與事件相關的鍵盤的按鍵 [System.Windows.Input.Key枚舉]
switch (e.Key)
// 按 Up 鍵後 textBox 對象向 上 移動 1 個像素
// Up 鍵所對應的 e.PlatformKeyCode == 38
// 當獲得的 e.Key == Key.Unknown 時,可以使用 e.PlatformKeyCode 來确定使用者所按的鍵
case Key.Up:
textBox.SetValue(Canvas.TopProperty, y - 1);
break;
// 按 Down 鍵後 textBox 對象向 下 移動 1 個像素
// Down 鍵所對應的 e.PlatformKeyCode == 40
case Key.Down:
textBox.SetValue(Canvas.TopProperty, y + 1);
// 按 Left 鍵後 textBox 對象向 左 移動 1 個像素
// Left 鍵所對應的 e.PlatformKeyCode == 37
case Key.Left:
textBox.SetValue(Canvas.LeftProperty, x - 1);
// 按 Right 鍵後 textBox 對象向 右 移動 1 個像素
// Right 鍵所對應的 e.PlatformKeyCode == 39
case Key.Right:
textBox.SetValue(Canvas.LeftProperty, x + 1);
default:
// 同上:Key.W - 向上移動; Key.S - 向下移動; Key.A - 向左移動; Key.D - 向右移動
// KeyEventArgs.Handled - 是否處理過此事件
// 如果在文本框内敲 W ,那麼文本框會向上移動,而且文本框内也會被輸入 W
// 如果隻想移動文本框,而不輸入 W ,那麼可以設定 KeyEventArgs.Handled = true 告知此事件已經被處理完畢
case Key.W:
e.Handled = true;
case Key.S:
case Key.A:
case Key.D:
private void userControl_KeyUp(object sender, KeyEventArgs e)
/*
System.Windows.Input.Keyboard.Modifiers - 目前按下的輔助鍵 [System.Windows.Input.ModifierKeys枚舉]
ModifierKeys.None - 無
ModifierKeys.Alt - Alt 鍵
ModifierKeys.Control - Ctrl 鍵
ModifierKeys.Shift - Shift 鍵
ModifierKeys.Windows - Windows 鍵
ModifierKeys.Apple - Apple 鍵(蘋果電腦)
*/
// 按 Ctrl + M 則将 textBox 的位置設定為其初始位置
if (System.Windows.Input.Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.M)
textBox.SetValue(Canvas.LeftProperty, 0d);
textBox.SetValue(Canvas.TopProperty, 0d);
OK
本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/343044,如需轉載請自行聯系原作者