设为首页 收藏本站
查看: 1754|回复: 0

Codename.Windows.Input — 让Silverlight使用右键和滚轮事件更简单[2008-12-12更新]

[复制链接]

尚未签到

发表于 2015-4-30 11:29:02 | 显示全部楼层 |阅读模式
  源代码下载:Codename.Windows.Input v0.9.2
  更新:
  [2008-12-12]
  在Silverlight 2正式版中可以运行。
  [2008-7-23]
  据一网友反映,鼠标按钮状态在MouseButtonDown和MouseButtonUp事件中实现的不正确,现已更正并添加了一点小功能,谢谢此网友提醒。
  
  众所周知,Silvelight现在不支持右键和滚轮事件,不过可以通过另类途径让Silverlight实现右键和滚轮事件。现在网上有好多关于实现右键和滚轮事件的文章,不过好像都没有将其封装成使用简洁便利的类库。为了方便大家使用,故本人将其封装成使用方便的类库。由于本人能力有限,类库封装的并不完美,如当前版本不支持事件路由等,不过不影响使用。
  测试如下:
  
  具体使用如下:
  使用MouseEvent类中以下函数即可实现相应的功能。

public static bool AttachMouseButtonDownEvent(System.Windows.UIElement element, System.EventHandler handler)
public static bool AttachMouseButtonUpEvent(System.Windows.UIElement element, System.EventHandler handler)
public static bool AttachMouseWheelEvent(System.Windows.UIElement element, System.EventHandler handler)
public static void DetachMouseButtonDownEvent(System.Windows.UIElement element, System.EventHandler handler)
public static void DetachMouseRightButtonUpEvent(System.Windows.UIElement element, System.EventHandler handler)
public static void DetachMouseWheelEvent(System.Windows.UIElement element, System.EventHandler handler)
  
  使用MouseEvent类中以下属性可以直接获得鼠标按钮的状态。

public static Codename.Windows.Input.MouseButtonState LeftButton { get; }
public static Codename.Windows.Input.MouseButtonState MiddleButton { get; }
public static Codename.Windows.Input.MouseButtonState RightButton { get; }
public static Codename.Windows.Input.MouseButton ChangedButton { get; }
public static Codename.Windows.Input.MouseButtonState ButtonState { get; }
public static bool PreventContextMenu { set; get; }
  
  设计类图如下:
DSC0000.png
  
  详细的设计请参考代码和代码中的注释
  代码如下:

DSC0001.gif DSC0002.gif /**///////////////////////////////////////////////////////////////////////////////////////////
DSC0003.gif //作者:宋剑飞
//网名:Codename
//QQ:247823451
//邮箱:codename.net@hotmail.com
//声明:本代码可以无偿使用,如将本代码用于商业用途,必须经本人许可,否则视为侵权。
/**///////////////////////////////////////////////////////////////////////////////////////////

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Browser;
using System.Collections.Generic;

namespace Codename.Windows.Input
DSC0004.gif {
DSC0005.gif DSC0006.gif     MouseEvent#region MouseEvent
DSC0007.gif
    /**////
    /// 为 UIElement 提供鼠标中键、右键和滚轮滚动事件。(要使用鼠标的中键和右键功能,请将 Silverlight 控件的 windowless 属性设为 true)
DSC0008.gif     ///
    public static class MouseEvent
    {
        UIElementMouseStateDictionary#region UIElementMouseStateDictionary

        //UIElementMouseState 字典
        //key 为 UIElement
        //value 为 UIElementMouseState
        private static Dictionary _uiElementMouseStateDictionary;
        private static Dictionary UIElementMouseStateDictionary
        {
            get
            {
                //该字典用单件模式实现,按需实例化该字典
                if (_uiElementMouseStateDictionary == null && HtmlPage.IsEnabled)
                {
                    _uiElementMouseStateDictionary = new Dictionary();
                }
                return _uiElementMouseStateDictionary;
            }
        }

        #endregion

        DomMouseButtonEvent#region DomMouseButtonEvent
        
        //该字段用于表明 DomMouseEvent 是否已注册
        static bool _isRegister;
        private static void _registerDomMouseButtonEvent()
        {
            //确保 DomMouseEvent 只被注册一次
            if (!_isRegister)
            {
                //注册 HtmlObject 对象的 onmousedown 事件
                HtmlPage.Plugin.AttachEvent("onmousedown", _handleMouseButtonDown);

                //注册 HtmlObject 对象的 onmouseup 事件
                HtmlPage.Plugin.AttachEvent("onmouseup", _handleMouseButtonUp);

                //注册 HtmlObject 对象的 oncontextmenu 事件
                _isRegister = HtmlPage.Plugin.AttachEvent("oncontextmenu", _handleContextMenu);
            }
        }

        //onmousedown 事件的处理函数
        private static void _handleMouseButtonDown(object sender, HtmlEventArgs args)
        {
            //更新鼠标按钮的状态
            _updateButtonsState(args.MouseButton, MouseButtonState.Pressed);

            //触发 MouseButtonDown 事件
            _raiseMouseButtonDownEvent();
        }

        //onmouseup 事件的处理函数
        private static void _handleMouseButtonUp(object sender, HtmlEventArgs args)
        {
            //更新鼠标按钮的状态
            _updateButtonsState(args.MouseButton, MouseButtonState.Released);

            //触发 MouseButtonUp 事件
            _raiseMouseButtonUpEvent();
        }

        //oncontextmenu 事件的处理函数
        private static void _handleContextMenu(object sender, HtmlEventArgs args)
        {
            if (_preventContextMenu)
            { args.PreventDefault(); }
        }

        PreventContextMenu#region PreventContextMenu
        private static bool _preventContextMenu = true;
        /**////
        /// 获得或设置一个值,该值用来指示是否禁止默认的右键配置菜单显示(默认为禁止)。
        ///
        /// 如果返回为 true ,则表示禁止默认的右键配置菜单显示,否则显示默认的配置菜单。
        public static bool PreventContextMenu
        {
            get { return _preventContextMenu; }
            set { _preventContextMenu = value; }
        }
        #endregion

        #endregion

        MouseButtonState#region MouseButtonState

        LeftButton#region LeftButton
        static MouseButtonState _leftButton;
        /**////
        /// 获取鼠标左键的当前状态。
        ///
        /// 鼠标左键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。
        public static MouseButtonState LeftButton
        {
            get { return _leftButton; }
        }
        #endregion

        MiddleButton#region MiddleButton
        static MouseButtonState _middleButton;
        /**////
        /// 获取鼠标中键的当前状态。
        ///
        /// 鼠标中键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。没有默认值。
        public static MouseButtonState MiddleButton
        {
            get { return _middleButton; }
        }
        #endregion

        RightButton#region RightButton
        static MouseButtonState _rightButton;
        /**////
        /// 获取鼠标右键的当前状态。
        ///
        /// 鼠标右键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。
        public static MouseButtonState RightButton
        {
            get { return _rightButton; }
        }
        #endregion

        ButtonState#region ButtonState
        static MouseButtonState _buttonState;
        /**////
        /// 获取改变的按钮的状态。
        ///
        /// 改变的按钮的状态。
        public static MouseButtonState ButtonState
        {
            get { return _buttonState; }
        }
        #endregion

        ChangedButton#region ChangedButton
        static MouseButton _changedButton;
        /**////
        /// 获取改变状态的按钮。
        ///
        /// 改变状态的按钮。
        public static MouseButton ChangedButton
        {
            get { return _changedButton; }
        }
        #endregion

        _updateButtonsState#region _updateButtonsState

        //保存所有已按下的鼠标按钮
        private static MouseButtons _mouseDownButtons;

        //更新鼠标按钮当前的状态
        private static void _updateButtonsState(MouseButtons buttons, MouseButtonState state)
        {
            MouseButtons changedBtn = MouseButtons.None;

            switch (state)
            {
                case MouseButtonState.Pressed:
                    //当有鼠标按钮按下时

                    //用异或求出改变的按键
                    changedBtn = (MouseButtons)(_mouseDownButtons ^ buttons);
                    //buttons 为当前所有已按下的按钮,直接赋值
                    _mouseDownButtons = buttons;
                    break;
                case MouseButtonState.Released:
                    //当有鼠标按钮释放时

                    //buttons 为当前释放的按钮,直接赋值
                    changedBtn = buttons;
                    //buttons 求反,然后再跟 _mouseDownButtons 相与,得到的值才为当前所有已按下的按钮
                    _mouseDownButtons &= (~buttons);
                    break;
            }

            //更新属性 ChangedButton
            switch (changedBtn)
            {
                case MouseButtons.Left:
                    _changedButton = MouseButton.Left;
                    break;
                case MouseButtons.Middle:
                    _changedButton = MouseButton.Middle;
                    break;
                case MouseButtons.Right:
                    _changedButton = MouseButton.Right;
                    break;
            }

            //更新属性 LeftButton,MiddleButton,RightButton
            _leftButton = MouseButtonState.Released;
            _middleButton = MouseButtonState.Released;
            _rightButton = MouseButtonState.Released;

            if ((_mouseDownButtons & MouseButtons.Left) > 0)
            {
                _leftButton = MouseButtonState.Pressed;
            }

            if ((_mouseDownButtons & MouseButtons.Middle) > 0)
            {
                _middleButton = MouseButtonState.Pressed;
            }

            if ((_mouseDownButtons & MouseButtons.Right) > 0)
            {
                _rightButton = MouseButtonState.Pressed;
            }

            //更新属性 ButtonState
            _buttonState = state;
        }
        #endregion

        #endregion

        MouseButtonDownEvent#region MouseButtonDownEvent

        MouseButtonDownEventDictionary#region MouseButtonDownEventDictionary
        //MouseButtonDownEvent 字典
        //key 为 UIElementMouseState
        //value 为 EventHandler
        private static Dictionary _mouseButtonDownEventDictionary;
        private static Dictionary MouseButtonDownEventDictionary
        {
            get
            {
                //该字典用单件模式实现,按需实例化该字典
                if (_mouseButtonDownEventDictionary == null && HtmlPage.IsEnabled)
                {
                    _mouseButtonDownEventDictionary = new Dictionary();

                    //必须调用该函数,否则点击右键时会显示默认的配置菜单
                    _registerDomMouseButtonEvent();
                }
                return _mouseButtonDownEventDictionary;
            }
        }
        #endregion

        _raiseMouseButtonDownEvent#region _raiseMouseButtonDownEvent
        //触发 MouseButtonDown 事件
        private static void _raiseMouseButtonDownEvent()
        {
            //当 MouseButtonDown 事件被注册过时
            if (_mouseButtonDownEventDictionary != null)
            {
                //循环处理 UIElementMouseStateDictionary 中的所有的 UIElementMouseState 对象
                foreach (UIElementMouseState state in UIElementMouseStateDictionary.Values)
                {
                    //判断 UIElementMouseState 对象是否有焦点,且在 MouseButtonDownEventDictionary 注册过事件
                    if (state.UIElementMouseEventArgs != null && MouseButtonDownEventDictionary.ContainsKey(state))
                    {
                        //创建一个新的 MouseButtonEventArgs 对象
                        MouseButtonEventArgs eventArgs = new MouseButtonEventArgs(state);

                        //触发该事件
                        MouseButtonDownEventDictionary[state](state.UIElement, eventArgs);
                    }
                }
            }
        }
        #endregion

        AttachMouseButtonDownEvent#region AttachMouseButtonDownEvent
        /**////
        /// 添加 (element)UIElement 的 MouseButtonDown 事件处理函数(当该函数调用成功时,默认的右键配置菜单将被屏蔽)。
        ///
        /// 触发该事件的元素。
        /// 要添加的处理该事件的函数。
        /// 如果添加处理函数成功返回 true ,否则返回 false。
        public static bool AttachMouseButtonDownEvent(UIElement element, EventHandler handler)
        {
            //当 element 为 null 或 handler 为 null 时,返回 false,没有可添加的委托
            if (element == null || handler == null)
            {
                return false;
            }

            UIElementMouseState uiElementMouseState;

            //从 UIElementMouseStateDictionary 中获取 uiElementMouseState(UIElementMouseState) 对象
            if (UIElementMouseStateDictionary.TryGetValue(element, out uiElementMouseState))
            {
                //如果可以获得,则说明其他事件已添加此条目

                //判断 MouseButtonDownEventDictionary 中是否含有键 uiElementMouseState(UIElementMouseState)
                //注意:必须使用函数 ContainsKey ,不能使用函数 TryGetValue,使用后者会导致当事件添加两个或两个以上事件处理函数时,无法添加事件处理函数
                if (MouseButtonDownEventDictionary.ContainsKey(uiElementMouseState))
                {
                    //如果有,则说明该事件已经被注册过,只需在该委托上直接附加
                    MouseButtonDownEventDictionary[uiElementMouseState] += handler;
                }
                else
                {
                    //如果没有,则说明该事件是第一次注册,需在 MouseButtonDownEventDictionary 中添加相关条目
                    MouseButtonDownEventDictionary.Add(uiElementMouseState, handler);
                }
            }
            else
            {
                //如果获取不到,则需添加相关条目

                uiElementMouseState = new UIElementMouseState(element);

                //在 UIElementMouseStateDictionary 中添加相关条目
                UIElementMouseStateDictionary.Add(element, uiElementMouseState);

                //在 MouseButtonDownEventDictionary 中添加相关条目
                MouseButtonDownEventDictionary.Add(uiElementMouseState, handler);
            }
            return true;
        }
        #endregion

        DetachMouseButtonDownEvent#region DetachMouseButtonDownEvent
        /**////
        /// 移除 (element)UIElement 的 MouseButtonDown 事件处理函数。
        ///
        /// 触发该事件的元素。
        /// 要移除的处理该事件的函数。
        public static void DetachMouseButtonDownEvent(UIElement element, EventHandler handler)
        {
            //当 element 为 null 或 handler 为 null 或 _mouseButtonDownEventDictionary 为 null 时,直接返回函数,没有可删除的委托
            if (element == null || handler == null || _mouseButtonDownEventDictionary == null)
            {
                return;
            }

            UIElementMouseState uiElementMouseState;

            //当 UIElementMouseStateDictionary 中无法获得 uiElementMouseState(UIElementMouseState) 时,直接返回函数
            //说明还没有添加过跟 element(UIElement) 相关联的任何事件
            if (!UIElementMouseStateDictionary.TryGetValue(element, out uiElementMouseState))
            {
                return;
            }

            //当 MouseButtonDownEventDictionary 中不含有键 uiElementMouseState(UIElementMouseState) 时,直接返回函数
            //说明还没有添加过跟 element(UIElement) 相关联的 MouseButtonDown 事件
            //注意:必须使用函数 ContainsKey ,不能使用函数 TryGetValue,使用后者会导致当事件跟两个或两个以上事件处理函数相关联时,无法移除事件处理函数
            if (!MouseButtonDownEventDictionary.ContainsKey(uiElementMouseState))
            {
                return;
            }

            //在事件中删除委托并判断是否为 null
            //当事件为 null 时说明已不需该事件,可以从 MouseButtonDownEventDictionary 中移除
            if ((MouseButtonDownEventDictionary[uiElementMouseState] -= handler) == null)
            {
                //从 MouseButtonDownEventDictionary 中移除该事件
                MouseButtonDownEventDictionary.Remove(uiElementMouseState);

                //判断其它事件是否还包含跟 element(UIElement) 相关联的委托
                if (!MouseButtonUpEventDictionary.ContainsKey(uiElementMouseState) && !MouseWheelEventDictionary.ContainsKey(uiElementMouseState))
                {
                    //如果没有,则说明已经没有任何事件跟 element(UIElement) 相关联
                    //可以从 UIElementMouseStateDictionary 中移除
                    UIElementMouseStateDictionary.Remove(element);
                }
            }
        }

        #endregion

        #endregion

        MouseButtonUpEvent#region MouseButtonUpEvent

        MouseButtonUpEventDictionary#region MouseButtonUpEventDictionary
        //MouseButtonUpEvent 字典
        //key 为 UIElementMouseState
        //value 为 EventHandler
        private static Dictionary _mouseButtonUpEventDictionary;
        private static Dictionary MouseButtonUpEventDictionary
        {
            get
            {
                //该字典用单件模式实现,按需实例化该字典
                if (_mouseButtonUpEventDictionary == null && HtmlPage.IsEnabled)
                {
                    _mouseButtonUpEventDictionary = new Dictionary();
                    //必须调用该函数,否则点击右键时会显示默认的配置菜单
                    _registerDomMouseButtonEvent();
                }
                return _mouseButtonUpEventDictionary;
            }
        }
        #endregion

        _raiseMouseButtonUpEvent#region _raiseMouseButtonUpEvent
        //触发 MouseButtonUp 事件
        private static void _raiseMouseButtonUpEvent()
        {
            //当 MouseButtonUp 事件被注册过时
            if (_mouseButtonUpEventDictionary != null)
            {
                //循环处理 UIElementMouseStateDictionary 中的所有的 UIElementMouseState 对象
                foreach (UIElementMouseState state in UIElementMouseStateDictionary.Values)
                {
                    //判断 UIElementMouseState 对象是否有焦点,且在 MouseButtonDownEventDictionary 注册过事件
                    if (state.UIElementMouseEventArgs != null && MouseButtonUpEventDictionary.ContainsKey(state))
                    {
                        //创建一个新的 MouseButtonEventArgs 对象
                        MouseButtonEventArgs eventArgs = new MouseButtonEventArgs(state);

                        //触发该事件
                        MouseButtonUpEventDictionary[state](state.UIElement, eventArgs);
                    }
                }
            }
        }
        #endregion

        AttachMouseButtonUpEvent#region AttachMouseButtonUpEvent

        /**////
        /// 添加 (element)UIElement 的 MouseButtonUp 事件处理函数(当该函数调用成功时,默认的右键配置菜单将被屏蔽)。
        ///
        /// 触发该事件的元素。
        /// 要添加的处理该事件的函数。
        /// 如果添加处理函数成功返回 true ,否则返回 false。
        public static bool AttachMouseButtonUpEvent(UIElement element, EventHandler handler)
        {
            //当 element 为 null 或 handler 为 null 时,返回 false,没有可添加的委托
            if (element == null || handler == null)
            {
                return false;
            }

            UIElementMouseState uiElementMouseState;

            //从 UIElementMouseStateDictionary 中获取 uiElementMouseState(UIElementMouseState) 对象
            if (UIElementMouseStateDictionary.TryGetValue(element, out uiElementMouseState))
            {
                //如果可以获得,则说明其他事件已添加此条目

                //判断 MouseButtonUpEventDictionary 中是否含有键 uiElementMouseState(UIElementMouseState)
                //注意:必须使用函数 ContainsKey ,不能使用函数 TryGetValue,使用后者会导致当事件添加两个或两个以上事件处理函数时,无法添加事件处理函数
                if (MouseButtonUpEventDictionary.ContainsKey(uiElementMouseState))
                {
                    //如果有,则说明该事件已经被注册过,只需在该委托上直接附加
                    MouseButtonUpEventDictionary[uiElementMouseState] += handler;
                }
                else
                {
                    //如果没有,则说明该事件是第一次注册,需在 MouseButtonUpEventDictionary 中添加相关条目
                    MouseButtonUpEventDictionary.Add(uiElementMouseState, handler);
                }
            }
            else
            {
                //如果获取不到,则需添加相关条目

                uiElementMouseState = new UIElementMouseState(element);

                //在 UIElementMouseStateDictionary 中添加相关条目
                UIElementMouseStateDictionary.Add(element, uiElementMouseState);

                //在 MouseButtonUpEventDictionary 中添加相关条目
                MouseButtonUpEventDictionary.Add(uiElementMouseState, handler);
            }
            return true;
        }
        #endregion

        DetachMouseRightButtonUpEvent#region DetachMouseRightButtonUpEvent
        /**////
        /// 移除 (element)UIElement 的 MouseButtonUp 事件处理函数。
        ///
        /// 触发该事件的元素。
        /// 要移除的处理该事件的函数。
        public static void DetachMouseRightButtonUpEvent(UIElement element, EventHandler handler)
        {
            //当 element 为 null 或 handler 为 null 或 _mouseButtonUpEventDictionary 为 null 时,直接返回函数,没有可删除的委托
            if (element == null || handler == null || _mouseButtonUpEventDictionary == null)
            {
                return;
            }

            UIElementMouseState uiElementMouseState;

            //当 UIElementMouseStateDictionary 中无法获得 uiElementMouseState(UIElementMouseState) 时,直接返回函数
            //说明还没有添加过跟 element(UIElement) 相关联的任何事件
            if (!UIElementMouseStateDictionary.TryGetValue(element, out uiElementMouseState))
            {
                return;
            }

            //当 MouseButtonUpEventDictionary 中不含有键 uiElementMouseState(UIElementMouseState) 时,直接返回函数
            //说明还没有添加过跟 element(UIElement) 相关联的 MouseButtonUp 事件
            //注意:必须使用函数 ContainsKey ,不能使用函数 TryGetValue,使用后者会导致当事件跟两个或两个以上事件处理函数相关联时,无法移除事件处理函数
            if (!MouseButtonUpEventDictionary.ContainsKey(uiElementMouseState))
            {
                return;
            }

            //在事件中删除委托并判断是否为 null
            //当事件为 null 时说明已不需该事件,可以从 MouseButtonUpEventDictionary 中移除
            if ((MouseButtonUpEventDictionary[uiElementMouseState] -= handler) == null)
            {
                //从 MouseButtonUpEventDictionary 中移除该事件
                MouseButtonUpEventDictionary.Remove(uiElementMouseState);

                //判断其它事件是否还包含跟 element(UIElement) 相关联的委托
                if (!MouseButtonDownEventDictionary.ContainsKey(uiElementMouseState) && !MouseWheelEventDictionary.ContainsKey(uiElementMouseState))
                {
                    //如果没有,则说明已经没有任何事件跟 element(UIElement) 相关联
                    //可以从 UIElementMouseStateDictionary 中移除
                    UIElementMouseStateDictionary.Remove(element);
                }
            }
        }

        #endregion

        #endregion

        MouseWheelEvent#region MouseWheelEvent

        MouseWheelEventDictionary#region MouseWheelEventDictionary
        //MouseWheelEvent 字典
        //key 为 UIElementMouseState
        //value 为 EventHandler
        private static Dictionary _mouseWheelEventDictionary;
        private static Dictionary MouseWheelEventDictionary
        {
            get
            {
                //该字典用单件模式实现,按需实例化该字典
                if (_mouseWheelEventDictionary == null && HtmlPage.IsEnabled)
                {
                    _mouseWheelEventDictionary = new Dictionary();
                    //注册 HtmlObject 对象的 onmousewheel 事件
                    HtmlPage.Plugin.AttachEvent("onmousewheel", _handleMouseWheel);
                }
                return _mouseWheelEventDictionary;
            }
        }

        //onmousewheel 事件的处理函数
        private static void _handleMouseWheel(object sender, HtmlEventArgs args)
        {
            double delta = 0;

            ScriptObject eventObj = args.EventObject;

            if (eventObj.GetProperty("wheelDelta") != null)
            {
                delta = ((double)eventObj.GetProperty("wheelDelta")) / 120;

                if (HtmlPage.Window.GetProperty("opera") != null)
                { delta = -delta; }
            }
            else
            {
                if (eventObj.GetProperty("detail") != null)
                {
                    delta = -((double)eventObj.GetProperty("detail")) / 3;

                    if (HtmlPage.BrowserInformation.UserAgent.IndexOf("Macintosh") != -1)
                        delta = delta * 3;
                }
            }

            if (delta != 0)
            {
                MouseWheelEventArgs wheelArgs = null;

                foreach (UIElementMouseState state in UIElementMouseStateDictionary.Values)
                {
                    if (state.UIElementMouseEventArgs != null && MouseWheelEventDictionary.ContainsKey(state))
                    {
                        //创建一个新的 MouseWheelEventArgs 对象
                        wheelArgs = new MouseWheelEventArgs(delta, state);

                        //触发该事件
                        MouseWheelEventDictionary[state](state.UIElement, wheelArgs);

                        //阻止浏览器响应鼠标滚动事件
                        args.PreventDefault();
                    }
                }

            }
        }
        #endregion

        AttachMouseWheelEvent#region AttachMouseWheelEvent
        /**////
        /// 添加 (element)UIElement 的 MouseWheel 事件处理函数。
        ///
        /// 触发该事件的元素。
        /// 要添加的处理该事件的函数。
        /// 如果添加处理函数成功返回 true ,否则返回 false。
        public static bool AttachMouseWheelEvent(UIElement element, EventHandler handler)
        {
            //当 element 为 null 或 handler 为 null 时,返回 false,没有可添加的委托
            if (element == null || handler == null)
            {
                return false;
            }

            UIElementMouseState uiElementMouseState;

            //从 UIElementMouseStateDictionary 中获取 uiElementMouseState(UIElementMouseState) 对象
            if (UIElementMouseStateDictionary.TryGetValue(element, out uiElementMouseState))
            {
                //如果可以获得,则说明其他事件已添加此条目

                //判断 MouseWheelEventDictionary 中是否含有键 uiElementMouseState(UIElementMouseState)
                //注意:必须使用函数 ContainsKey ,不能使用函数 TryGetValue,使用后者会导致当事件添加两个或两个以上事件处理函数时,无法添加事件处理函数
                if (MouseWheelEventDictionary.ContainsKey(uiElementMouseState))
                {
                    //如果有,则说明该事件已经被注册过,只需在该委托上直接附加
                    MouseWheelEventDictionary[uiElementMouseState] += handler;
                }
                else
                {
                    //如果没有,则说明该事件是第一次注册,需在 MouseWheelEventDictionary 中添加相关条目
                    MouseWheelEventDictionary.Add(uiElementMouseState, handler);
                }
            }
            else
            {
                //如果获取不到,则需添加相关条目

                uiElementMouseState = new UIElementMouseState(element);

                //在 UIElementMouseStateDictionary 中添加相关条目
                UIElementMouseStateDictionary.Add(element, uiElementMouseState);

                //在 MouseWheelEventDictionary 中添加相关条目
                MouseWheelEventDictionary.Add(uiElementMouseState, handler);
            }
            return true;
        }
        #endregion

        DetachMouseWheelEvent#region DetachMouseWheelEvent
        /**////
        /// 移除 (element)UIElement 的 MouseWheel 事件处理函数。
        ///
        /// 触发该事件的元素。
        /// 要移除的处理该事件的函数。
        public static void DetachMouseWheelEvent(UIElement element, EventHandler handler)
        {
            //当 element 为 null 或 handler 为 null 或 _mouseWheelEventDictionary 为 null 时,直接返回函数,没有可删除的委托
            if (element == null || handler == null || _mouseWheelEventDictionary == null)
            {
                return;
            }

            UIElementMouseState uiElementMouseState;

            //当 UIElementMouseStateDictionary 中无法获得 uiElementMouseState(UIElementMouseState) 时,直接返回函数
            //说明还没有添加过跟 element(UIElement) 相关联的任何事件
            if (!UIElementMouseStateDictionary.TryGetValue(element, out uiElementMouseState))
            {
                return;
            }

            //当 MouseWheelEventDictionary 中不含有键 uiElementMouseState(UIElementMouseState) 时,直接返回函数
            //说明还没有添加过跟 element(UIElement) 相关联的 MouseWheel 事件
            //注意:必须使用函数 ContainsKey ,不能使用函数 TryGetValue,使用后者会导致当事件跟两个或两个以上事件处理函数相关联时,无法移除事件处理函数
            if (!MouseWheelEventDictionary.ContainsKey(uiElementMouseState))
            {
                return;
            }

            //在事件中删除委托并判断是否为 null
            //当事件为 null 时说明已不需该事件,可以从 MouseWheelEventDictionary 中移除
            if ((MouseWheelEventDictionary[uiElementMouseState] -= handler) == null)
            {
                //从 MouseWheelEventDictionary 中移除该事件
                MouseWheelEventDictionary.Remove(uiElementMouseState);

                //判断其它事件是否还包含跟 element(UIElement) 相关联的委托
                if (!MouseButtonUpEventDictionary.ContainsKey(uiElementMouseState) && !MouseButtonDownEventDictionary.ContainsKey(uiElementMouseState))
                {
                    //如果没有,则说明已经没有任何事件跟 element(UIElement) 相关联
                    //可以从 UIElementMouseStateDictionary 中移除
                    UIElementMouseStateDictionary.Remove(element);
                }
            }
        }

        #endregion

        #endregion
    }
    #endregion

    UIElementMouseState#region UIElementMouseState

    //该类用于确定 UIElement 是否实现鼠标事件
    internal class UIElementMouseState
    {
        //该字段用来实现 MouseButtonEventArgs 和 MouseWheelEventArgs 的 GetPosition 函数
        //同时该字段用来判断该 UIElement 是否可以响应鼠标事件,如果该字段为 null 时,表示不能响应鼠标事件,否则表示可以响应鼠标事件
        internal MouseEventArgs UIElementMouseEventArgs;
        internal UIElement UIElement;

        public UIElementMouseState(UIElement element)
        {
            UIElement = element;

            UIElement.MouseEnter += new System.Windows.Input.MouseEventHandler(element_MouseEnter);
            UIElement.MouseLeave += new System.Windows.Input.MouseEventHandler(element_MouseLeave);
            UIElement.MouseMove += new System.Windows.Input.MouseEventHandler(element_MouseMove);
        }
        //处理 UIElement 的 MouseMove 事件
        private void element_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            //该 UIElement 可以响应鼠标事件
            UIElementMouseEventArgs = e;
        }
        //处理 UIElement 的 MouseLeave 事件
        private void element_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            //该 UIElement 不能响应鼠标事件
            UIElementMouseEventArgs = null;
        }
        //处理 UIElement 的 MouseEnter 事件
        private void element_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            //该 UIElement 可以响应鼠标事件
            UIElementMouseEventArgs = e;
        }
    }

    #endregion

    MouseWheelEventArgs#region MouseWheelEventArgs

    /**////
    /// 为报告鼠标设备的鼠标滚轮增量值更改的事件提供数据。
    ///
    public class MouseWheelEventArgs : RoutedEventArgs
    {
        MouseEventArgs mouseEventArgs;

        internal MouseWheelEventArgs(double delta, UIElementMouseState mouseState)
        {
            mouseEventArgs = mouseState.UIElementMouseEventArgs;

            Source = mouseState.UIElement;
            Delta = delta;
        }
        /**////
        /// 返回鼠标指针相对于指定元素的位置。
        ///
        /// 在计算鼠标指针位置时用作参考框架的元素。
        /// 相对于指定对象的鼠标指针位置的 x 和 y 坐标。
        public Point GetPosition(UIElement relativeTo)
        {
            return mouseEventArgs.GetPosition(relativeTo);
        }

        /**////
        /// 获取指示鼠标滚轮变更量的值。
        ///
        /// 鼠标滚轮的变更量。如果鼠标滚轮朝上旋转(背离用户的方向),则该值为正;如果鼠标滚轮朝下旋转(朝着用户的方向),则该值为负。
        public double Delta
        { get; private set; }

    }

    #endregion

    MouseButtonEventArgs#region MouseButtonEventArgs

    /**////
    /// 为与鼠标按钮相关的事件提供数据。
    ///
    public class MouseButtonEventArgs : RoutedEventArgs
    {
        MouseEventArgs _mouseEventArgs;

        internal MouseButtonEventArgs(UIElementMouseState mouseState)
        {
            _mouseEventArgs = mouseState.UIElementMouseEventArgs;

            Source = mouseState.UIElement;
            Handled = true;
        }

        /**////
        /// 返回鼠标指针相对于指定元素的位置。
        ///
        /// 在计算鼠标指针位置时用作参考框架的元素。
        /// 相对于指定对象的鼠标指针位置的 x 和 y 坐标。
        public Point GetPosition(UIElement relativeTo)
        {
            return _mouseEventArgs.GetPosition(relativeTo);
        }

        /**////
        /// 获取鼠标左键的当前状态。
        ///
        /// 鼠标左键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。
        public MouseButtonState LeftButton
        {
            get { return MouseEvent.LeftButton; }
        }

        /**////
        /// 获取鼠标中键的当前状态。
        ///
        /// 鼠标中键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。没有默认值。
        public MouseButtonState MiddleButton
        {
            get { return MouseEvent.MiddleButton; }
        }

        /**////
        /// 获取鼠标右键的当前状态。
        ///
        /// 鼠标右键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。
        public MouseButtonState RightButton
        {
            get { return MouseEvent.RightButton; }
        }

        /**////
        /// 获取改变的按钮的状态。
        ///
        /// 改变的按钮的状态。
        public MouseButtonState ButtonState
        {
            get { return MouseEvent.ButtonState; }
        }

        /**////
        /// 获取改变状态的按钮。
        ///
        /// 改变状态的按钮。
        public MouseButton ChangedButton
        {
            get { return MouseEvent.ChangedButton; }
        }

        /**////
        /// 获取或设置一个值,该值指示路由事件在路由过程中的事件处理当前状态。(该属性当前不可用)
        ///
        public bool Handled
        { get; set; }
    }

    #endregion

    MouseButton#region MouseButton

    /**////
    /// 定义用于指定鼠标设备上的按钮的值。
    ///
    public enum MouseButton
    {
        /**////
        /// 鼠标左按钮。
        ///
        Left = 1,
        /**////
        /// 鼠标中键。
        ///
        Middle = 2,
        /**////
        /// 鼠标右按钮。
        ///
        Right = 4
    }

    #endregion

    MouseButtonState#region MouseButtonState

    /**////
    /// 指定鼠标按钮的可能状态。
    ///
    public enum MouseButtonState
    {
        /**////
        /// 该按钮处于释放状态。
        ///
        Released,
        /**////
        /// 该按钮处于按下状态。
        ///
        Pressed
    }

    #endregion
DSC0009.gif }
  
  声明:本代码可以无偿使用,如将本代码用于商业用途,必须经本人许可,否则视为侵权。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-62234-1-1.html 上篇帖子: 安装 Team Foundation Server 2008 In Windows 2008 手记 下篇帖子: Create Windows Server 2008 cluster from the command line
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表