• 稳扎稳打Silverlight(13) 2.0交互之鼠标事件和键盘事件


    [索引页]
    [源码下载]


    稳扎稳打Silverlight(13) - 2.0交互之鼠标事件和键盘事件


    作者:webabcd


    介绍
    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
    http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html


    示例
    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)
            
    {
                ellipse.Fill 
    = new SolidColorBrush(Colors.Yellow);
            }


            
    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
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
        x:Name
    ="userControl"
        KeyDown
    ="userControl_KeyDown">
        
        
    <Canvas>
                
            
    <TextBox x:Name="textBox" Text="TextBox" />
            
        
    </Canvas>
        
    </UserControl>

    Keyboard.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 Keyboard : UserControl
        
    {
            
    public Keyboard()
            
    {
                InitializeComponent();

                
    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);
                        
    break;

                    
    // 按 Left 键后 textBox 对象向 左 移动 1 个像素
                    
    // Left 键所对应的 e.PlatformKeyCode == 37
                    case Key.Left:
                        textBox.SetValue(Canvas.LeftProperty, x 
    - 1);
                        
    break;

                    
    // 按 Right 键后 textBox 对象向 右 移动 1 个像素
                    
    // Right 键所对应的 e.PlatformKeyCode == 39 
                    case Key.Right:
                        textBox.SetValue(Canvas.LeftProperty, x 
    + 1);
                        
    break;

                    
    default:
                        
    break;
                }


                
    // 同上:Key.W - 向上移动; Key.S - 向下移动; Key.A - 向左移动; Key.D - 向右移动
                switch (e.Key)
                
    {
                    
    // KeyEventArgs.Handled - 是否处理过此事件

                    
    // 如果在文本框内敲 W ,那么文本框会向上移动,而且文本框内也会被输入 W
                    
    // 如果只想移动文本框,而不输入 W ,那么可以设置 KeyEventArgs.Handled = true 告知此事件已经被处理完毕
                    case Key.W:
                        textBox.SetValue(Canvas.TopProperty, y 
    - 1);
                        e.Handled 
    = true;
                        
    break;
                    
    case Key.S:
                        textBox.SetValue(Canvas.TopProperty, y 
    + 1);
                        e.Handled 
    = true;
                        
    break;
                    
    case Key.A:
                        textBox.SetValue(Canvas.LeftProperty, x 
    - 1);
                        e.Handled 
    = true;
                        
    break;
                    
    case Key.D:
                        textBox.SetValue(Canvas.LeftProperty, x 
    + 1);
                        e.Handled 
    = true;
                        
    break;
                    
    default:
                        
    break;
                }

            }


            
    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
    [源码下载]
  • 相关阅读:
    参考vue.js实现双向绑定的方法理解双向绑定原理(:Object.defineProperty和发布-订阅模式)
    不错的站点 博文
    使用C#动态生成Word文档/Excel文档的程序测试通过后,部署到IIS服务器上,不能正常使用的问题解决方案
    详解HTML<head> 头标签元素的意义以及使用场景
    css奇特用法之 IMG添加背景图片配合显示--效果惊艳
    .net面试题-15k+左右
    微信小程序IOS真机调试发生了SSL 错误,无法建立与该服务器的安全连接
    微信小程序自定义组件-下拉框
    微信小程序语音(A)发给别人(B),也能播放,是需要先把语音上传到自己的服务器上才可以
    微信小程序循环中点击一个元素,其他的元素不发生变化,类似点击一个循环中的语音,其他的不发生点击事件
  • 原文地址:https://www.cnblogs.com/webabcd/p/1332450.html
Copyright © 2020-2023  润新知