Codename.Windows.Input — 让Silverlight使用右键和滚轮事件更简单[2008-12-12更新]
源代码下载: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<mousebuttoneventargs> handler)
public static bool AttachMouseButtonUpEvent(System.Windows.UIElement element, System.EventHandler<MouseButtonEventArgs> handler)
public static bool AttachMouseWheelEvent(System.Windows.UIElement element, System.EventHandler<MouseWheelEventArgs> handler)
public static void DetachMouseButtonDownEvent(System.Windows.UIElement element, System.EventHandler<MouseButtonEventArgs> handler)
public static void DetachMouseRightButtonUpEvent(System.Windows.UIElement element, System.EventHandler<MouseButtonEventArgs> handler)
public static void DetachMouseWheelEvent(System.Windows.UIElement element, System.EventHandler<MouseWheelEventArgs> handler)
public static bool AttachMouseButtonUpEvent(System.Windows.UIElement element, System.EventHandler<MouseButtonEventArgs> handler)
public static bool AttachMouseWheelEvent(System.Windows.UIElement element, System.EventHandler<MouseWheelEventArgs> handler)
public static void DetachMouseButtonDownEvent(System.Windows.UIElement element, System.EventHandler<MouseButtonEventArgs> handler)
public static void DetachMouseRightButtonUpEvent(System.Windows.UIElement element, System.EventHandler<MouseButtonEventArgs> handler)
public static void DetachMouseWheelEvent(System.Windows.UIElement element, System.EventHandler<MouseWheelEventArgs> 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; }
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; }
设计类图如下:
详细的设计请参考代码和代码中的注释
代码如下:
/**///////////////////////////////////////////////////////////////////////////////////////////
//作者:宋剑飞
//网名: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
{
MouseEvent#region MouseEvent
/**//// <summary>
/// 为 UIElement 提供鼠标中键、右键和滚轮滚动事件。(要使用鼠标的中键和右键功能,请将 Silverlight 控件的 windowless 属性设为 true)
/// </summary>
public static class MouseEvent
{
UIElementMouseStateDictionary#region UIElementMouseStateDictionary
//UIElementMouseState 字典
//key 为 UIElement
//value 为 UIElementMouseState
private static Dictionary<UIElement, UIElementMouseState> _uiElementMouseStateDictionary;
private static Dictionary<UIElement, UIElementMouseState> UIElementMouseStateDictionary
{
get
{
//该字典用单件模式实现,按需实例化该字典
if (_uiElementMouseStateDictionary == null && HtmlPage.IsEnabled)
{
_uiElementMouseStateDictionary = new Dictionary<UIElement, UIElementMouseState>();
}
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;
/**//// <summary>
/// 获得或设置一个值,该值用来指示是否禁止默认的右键配置菜单显示(默认为禁止)。
/// </summary>
/// <returns>如果返回为 true ,则表示禁止默认的右键配置菜单显示,否则显示默认的配置菜单。</returns>
public static bool PreventContextMenu
{
get { return _preventContextMenu; }
set { _preventContextMenu = value; }
}
#endregion
#endregion
MouseButtonState#region MouseButtonState
LeftButton#region LeftButton
static MouseButtonState _leftButton;
/**//// <summary>
/// 获取鼠标左键的当前状态。
/// </summary>
/// <returns>鼠标左键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。</returns>
public static MouseButtonState LeftButton
{
get { return _leftButton; }
}
#endregion
MiddleButton#region MiddleButton
static MouseButtonState _middleButton;
/**//// <summary>
/// 获取鼠标中键的当前状态。
/// </summary>
/// <returns>鼠标中键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。没有默认值。</returns>
public static MouseButtonState MiddleButton
{
get { return _middleButton; }
}
#endregion
RightButton#region RightButton
static MouseButtonState _rightButton;
/**//// <summary>
/// 获取鼠标右键的当前状态。
/// </summary>
/// <returns>鼠标右键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。</returns>
public static MouseButtonState RightButton
{
get { return _rightButton; }
}
#endregion
ButtonState#region ButtonState
static MouseButtonState _buttonState;
/**//// <summary>
/// 获取改变的按钮的状态。
/// </summary>
/// <returns>改变的按钮的状态。</returns>
public static MouseButtonState ButtonState
{
get { return _buttonState; }
}
#endregion
ChangedButton#region ChangedButton
static MouseButton _changedButton;
/**//// <summary>
/// 获取改变状态的按钮。
/// </summary>
/// <returns>改变状态的按钮。</returns>
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<MouseButtonEventArgs>
private static Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>> _mouseButtonDownEventDictionary;
private static Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>> MouseButtonDownEventDictionary
{
get
{
//该字典用单件模式实现,按需实例化该字典
if (_mouseButtonDownEventDictionary == null && HtmlPage.IsEnabled)
{
_mouseButtonDownEventDictionary = new Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>>();
//必须调用该函数,否则点击右键时会显示默认的配置菜单
_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
/**//// <summary>
/// 添加 (element)UIElement 的 MouseButtonDown 事件处理函数(当该函数调用成功时,默认的右键配置菜单将被屏蔽)。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要添加的处理该事件的函数。</param>
/// <returns>如果添加处理函数成功返回 true ,否则返回 false。</returns>
public static bool AttachMouseButtonDownEvent(UIElement element, EventHandler<MouseButtonEventArgs> 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
/**//// <summary>
/// 移除 (element)UIElement 的 MouseButtonDown 事件处理函数。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要移除的处理该事件的函数。</param>
public static void DetachMouseButtonDownEvent(UIElement element, EventHandler<MouseButtonEventArgs> 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<MouseButtonEventArgs>
private static Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>> _mouseButtonUpEventDictionary;
private static Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>> MouseButtonUpEventDictionary
{
get
{
//该字典用单件模式实现,按需实例化该字典
if (_mouseButtonUpEventDictionary == null && HtmlPage.IsEnabled)
{
_mouseButtonUpEventDictionary = new Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>>();
//必须调用该函数,否则点击右键时会显示默认的配置菜单
_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
/**//// <summary>
/// 添加 (element)UIElement 的 MouseButtonUp 事件处理函数(当该函数调用成功时,默认的右键配置菜单将被屏蔽)。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要添加的处理该事件的函数。</param>
/// <returns>如果添加处理函数成功返回 true ,否则返回 false。</returns>
public static bool AttachMouseButtonUpEvent(UIElement element, EventHandler<MouseButtonEventArgs> 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
/**//// <summary>
/// 移除 (element)UIElement 的 MouseButtonUp 事件处理函数。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要移除的处理该事件的函数。</param>
public static void DetachMouseRightButtonUpEvent(UIElement element, EventHandler<MouseButtonEventArgs> 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<MouseButtonEventArgs>
private static Dictionary<UIElementMouseState, EventHandler<MouseWheelEventArgs>> _mouseWheelEventDictionary;
private static Dictionary<UIElementMouseState, EventHandler<MouseWheelEventArgs>> MouseWheelEventDictionary
{
get
{
//该字典用单件模式实现,按需实例化该字典
if (_mouseWheelEventDictionary == null && HtmlPage.IsEnabled)
{
_mouseWheelEventDictionary = new Dictionary<UIElementMouseState, EventHandler<MouseWheelEventArgs>>();
//注册 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
/**//// <summary>
/// 添加 (element)UIElement 的 MouseWheel 事件处理函数。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要添加的处理该事件的函数。</param>
/// <returns>如果添加处理函数成功返回 true ,否则返回 false。</returns>
public static bool AttachMouseWheelEvent(UIElement element, EventHandler<MouseWheelEventArgs> 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
/**//// <summary>
/// 移除 (element)UIElement 的 MouseWheel 事件处理函数。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要移除的处理该事件的函数。</param>
public static void DetachMouseWheelEvent(UIElement element, EventHandler<MouseWheelEventArgs> 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
/**//// <summary>
/// 为报告鼠标设备的鼠标滚轮增量值更改的事件提供数据。
/// </summary>
public class MouseWheelEventArgs : RoutedEventArgs
{
MouseEventArgs mouseEventArgs;
internal MouseWheelEventArgs(double delta, UIElementMouseState mouseState)
{
mouseEventArgs = mouseState.UIElementMouseEventArgs;
Source = mouseState.UIElement;
Delta = delta;
}
/**//// <summary>
/// 返回鼠标指针相对于指定元素的位置。
/// </summary>
/// <param name="relativeTo">在计算鼠标指针位置时用作参考框架的元素。</param>
/// <returns>相对于指定对象的鼠标指针位置的 x 和 y 坐标。</returns>
public Point GetPosition(UIElement relativeTo)
{
return mouseEventArgs.GetPosition(relativeTo);
}
/**//// <summary>
/// 获取指示鼠标滚轮变更量的值。
/// </summary>
/// <returns>鼠标滚轮的变更量。如果鼠标滚轮朝上旋转(背离用户的方向),则该值为正;如果鼠标滚轮朝下旋转(朝着用户的方向),则该值为负。</returns>
public double Delta
{ get; private set; }
}
#endregion
MouseButtonEventArgs#region MouseButtonEventArgs
/**//// <summary>
/// 为与鼠标按钮相关的事件提供数据。
/// </summary>
public class MouseButtonEventArgs : RoutedEventArgs
{
MouseEventArgs _mouseEventArgs;
internal MouseButtonEventArgs(UIElementMouseState mouseState)
{
_mouseEventArgs = mouseState.UIElementMouseEventArgs;
Source = mouseState.UIElement;
Handled = true;
}
/**//// <summary>
/// 返回鼠标指针相对于指定元素的位置。
/// </summary>
/// <param name="relativeTo">在计算鼠标指针位置时用作参考框架的元素。</param>
/// <returns>相对于指定对象的鼠标指针位置的 x 和 y 坐标。</returns>
public Point GetPosition(UIElement relativeTo)
{
return _mouseEventArgs.GetPosition(relativeTo);
}
/**//// <summary>
/// 获取鼠标左键的当前状态。
/// </summary>
/// <returns>鼠标左键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。</returns>
public MouseButtonState LeftButton
{
get { return MouseEvent.LeftButton; }
}
/**//// <summary>
/// 获取鼠标中键的当前状态。
/// </summary>
/// <returns>鼠标中键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。没有默认值。</returns>
public MouseButtonState MiddleButton
{
get { return MouseEvent.MiddleButton; }
}
/**//// <summary>
/// 获取鼠标右键的当前状态。
/// </summary>
/// <returns>鼠标右键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。</returns>
public MouseButtonState RightButton
{
get { return MouseEvent.RightButton; }
}
/**//// <summary>
/// 获取改变的按钮的状态。
/// </summary>
/// <returns>改变的按钮的状态。</returns>
public MouseButtonState ButtonState
{
get { return MouseEvent.ButtonState; }
}
/**//// <summary>
/// 获取改变状态的按钮。
/// </summary>
/// <returns>改变状态的按钮。</returns>
public MouseButton ChangedButton
{
get { return MouseEvent.ChangedButton; }
}
/**//// <summary>
/// 获取或设置一个值,该值指示路由事件在路由过程中的事件处理当前状态。(该属性当前不可用)
/// </summary>
public bool Handled
{ get; set; }
}
#endregion
MouseButton#region MouseButton
/**//// <summary>
/// 定义用于指定鼠标设备上的按钮的值。
/// </summary>
public enum MouseButton
{
/**//// <summary>
/// 鼠标左按钮。
/// </summary>
Left = 1,
/**//// <summary>
/// 鼠标中键。
/// </summary>
Middle = 2,
/**//// <summary>
/// 鼠标右按钮。
/// </summary>
Right = 4
}
#endregion
MouseButtonState#region MouseButtonState
/**//// <summary>
/// 指定鼠标按钮的可能状态。
/// </summary>
public enum MouseButtonState
{
/**//// <summary>
/// 该按钮处于释放状态。
/// </summary>
Released,
/**//// <summary>
/// 该按钮处于按下状态。
/// </summary>
Pressed
}
#endregion
}
//作者:宋剑飞
//网名: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
{
MouseEvent#region MouseEvent
/**//// <summary>
/// 为 UIElement 提供鼠标中键、右键和滚轮滚动事件。(要使用鼠标的中键和右键功能,请将 Silverlight 控件的 windowless 属性设为 true)
/// </summary>
public static class MouseEvent
{
UIElementMouseStateDictionary#region UIElementMouseStateDictionary
//UIElementMouseState 字典
//key 为 UIElement
//value 为 UIElementMouseState
private static Dictionary<UIElement, UIElementMouseState> _uiElementMouseStateDictionary;
private static Dictionary<UIElement, UIElementMouseState> UIElementMouseStateDictionary
{
get
{
//该字典用单件模式实现,按需实例化该字典
if (_uiElementMouseStateDictionary == null && HtmlPage.IsEnabled)
{
_uiElementMouseStateDictionary = new Dictionary<UIElement, UIElementMouseState>();
}
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;
/**//// <summary>
/// 获得或设置一个值,该值用来指示是否禁止默认的右键配置菜单显示(默认为禁止)。
/// </summary>
/// <returns>如果返回为 true ,则表示禁止默认的右键配置菜单显示,否则显示默认的配置菜单。</returns>
public static bool PreventContextMenu
{
get { return _preventContextMenu; }
set { _preventContextMenu = value; }
}
#endregion
#endregion
MouseButtonState#region MouseButtonState
LeftButton#region LeftButton
static MouseButtonState _leftButton;
/**//// <summary>
/// 获取鼠标左键的当前状态。
/// </summary>
/// <returns>鼠标左键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。</returns>
public static MouseButtonState LeftButton
{
get { return _leftButton; }
}
#endregion
MiddleButton#region MiddleButton
static MouseButtonState _middleButton;
/**//// <summary>
/// 获取鼠标中键的当前状态。
/// </summary>
/// <returns>鼠标中键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。没有默认值。</returns>
public static MouseButtonState MiddleButton
{
get { return _middleButton; }
}
#endregion
RightButton#region RightButton
static MouseButtonState _rightButton;
/**//// <summary>
/// 获取鼠标右键的当前状态。
/// </summary>
/// <returns>鼠标右键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。</returns>
public static MouseButtonState RightButton
{
get { return _rightButton; }
}
#endregion
ButtonState#region ButtonState
static MouseButtonState _buttonState;
/**//// <summary>
/// 获取改变的按钮的状态。
/// </summary>
/// <returns>改变的按钮的状态。</returns>
public static MouseButtonState ButtonState
{
get { return _buttonState; }
}
#endregion
ChangedButton#region ChangedButton
static MouseButton _changedButton;
/**//// <summary>
/// 获取改变状态的按钮。
/// </summary>
/// <returns>改变状态的按钮。</returns>
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<MouseButtonEventArgs>
private static Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>> _mouseButtonDownEventDictionary;
private static Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>> MouseButtonDownEventDictionary
{
get
{
//该字典用单件模式实现,按需实例化该字典
if (_mouseButtonDownEventDictionary == null && HtmlPage.IsEnabled)
{
_mouseButtonDownEventDictionary = new Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>>();
//必须调用该函数,否则点击右键时会显示默认的配置菜单
_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
/**//// <summary>
/// 添加 (element)UIElement 的 MouseButtonDown 事件处理函数(当该函数调用成功时,默认的右键配置菜单将被屏蔽)。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要添加的处理该事件的函数。</param>
/// <returns>如果添加处理函数成功返回 true ,否则返回 false。</returns>
public static bool AttachMouseButtonDownEvent(UIElement element, EventHandler<MouseButtonEventArgs> 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
/**//// <summary>
/// 移除 (element)UIElement 的 MouseButtonDown 事件处理函数。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要移除的处理该事件的函数。</param>
public static void DetachMouseButtonDownEvent(UIElement element, EventHandler<MouseButtonEventArgs> 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<MouseButtonEventArgs>
private static Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>> _mouseButtonUpEventDictionary;
private static Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>> MouseButtonUpEventDictionary
{
get
{
//该字典用单件模式实现,按需实例化该字典
if (_mouseButtonUpEventDictionary == null && HtmlPage.IsEnabled)
{
_mouseButtonUpEventDictionary = new Dictionary<UIElementMouseState, EventHandler<MouseButtonEventArgs>>();
//必须调用该函数,否则点击右键时会显示默认的配置菜单
_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
/**//// <summary>
/// 添加 (element)UIElement 的 MouseButtonUp 事件处理函数(当该函数调用成功时,默认的右键配置菜单将被屏蔽)。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要添加的处理该事件的函数。</param>
/// <returns>如果添加处理函数成功返回 true ,否则返回 false。</returns>
public static bool AttachMouseButtonUpEvent(UIElement element, EventHandler<MouseButtonEventArgs> 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
/**//// <summary>
/// 移除 (element)UIElement 的 MouseButtonUp 事件处理函数。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要移除的处理该事件的函数。</param>
public static void DetachMouseRightButtonUpEvent(UIElement element, EventHandler<MouseButtonEventArgs> 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<MouseButtonEventArgs>
private static Dictionary<UIElementMouseState, EventHandler<MouseWheelEventArgs>> _mouseWheelEventDictionary;
private static Dictionary<UIElementMouseState, EventHandler<MouseWheelEventArgs>> MouseWheelEventDictionary
{
get
{
//该字典用单件模式实现,按需实例化该字典
if (_mouseWheelEventDictionary == null && HtmlPage.IsEnabled)
{
_mouseWheelEventDictionary = new Dictionary<UIElementMouseState, EventHandler<MouseWheelEventArgs>>();
//注册 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
/**//// <summary>
/// 添加 (element)UIElement 的 MouseWheel 事件处理函数。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要添加的处理该事件的函数。</param>
/// <returns>如果添加处理函数成功返回 true ,否则返回 false。</returns>
public static bool AttachMouseWheelEvent(UIElement element, EventHandler<MouseWheelEventArgs> 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
/**//// <summary>
/// 移除 (element)UIElement 的 MouseWheel 事件处理函数。
/// </summary>
/// <param name="element">触发该事件的元素。</param>
/// <param name="handler">要移除的处理该事件的函数。</param>
public static void DetachMouseWheelEvent(UIElement element, EventHandler<MouseWheelEventArgs> 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
/**//// <summary>
/// 为报告鼠标设备的鼠标滚轮增量值更改的事件提供数据。
/// </summary>
public class MouseWheelEventArgs : RoutedEventArgs
{
MouseEventArgs mouseEventArgs;
internal MouseWheelEventArgs(double delta, UIElementMouseState mouseState)
{
mouseEventArgs = mouseState.UIElementMouseEventArgs;
Source = mouseState.UIElement;
Delta = delta;
}
/**//// <summary>
/// 返回鼠标指针相对于指定元素的位置。
/// </summary>
/// <param name="relativeTo">在计算鼠标指针位置时用作参考框架的元素。</param>
/// <returns>相对于指定对象的鼠标指针位置的 x 和 y 坐标。</returns>
public Point GetPosition(UIElement relativeTo)
{
return mouseEventArgs.GetPosition(relativeTo);
}
/**//// <summary>
/// 获取指示鼠标滚轮变更量的值。
/// </summary>
/// <returns>鼠标滚轮的变更量。如果鼠标滚轮朝上旋转(背离用户的方向),则该值为正;如果鼠标滚轮朝下旋转(朝着用户的方向),则该值为负。</returns>
public double Delta
{ get; private set; }
}
#endregion
MouseButtonEventArgs#region MouseButtonEventArgs
/**//// <summary>
/// 为与鼠标按钮相关的事件提供数据。
/// </summary>
public class MouseButtonEventArgs : RoutedEventArgs
{
MouseEventArgs _mouseEventArgs;
internal MouseButtonEventArgs(UIElementMouseState mouseState)
{
_mouseEventArgs = mouseState.UIElementMouseEventArgs;
Source = mouseState.UIElement;
Handled = true;
}
/**//// <summary>
/// 返回鼠标指针相对于指定元素的位置。
/// </summary>
/// <param name="relativeTo">在计算鼠标指针位置时用作参考框架的元素。</param>
/// <returns>相对于指定对象的鼠标指针位置的 x 和 y 坐标。</returns>
public Point GetPosition(UIElement relativeTo)
{
return _mouseEventArgs.GetPosition(relativeTo);
}
/**//// <summary>
/// 获取鼠标左键的当前状态。
/// </summary>
/// <returns>鼠标左键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。</returns>
public MouseButtonState LeftButton
{
get { return MouseEvent.LeftButton; }
}
/**//// <summary>
/// 获取鼠标中键的当前状态。
/// </summary>
/// <returns>鼠标中键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。没有默认值。</returns>
public MouseButtonState MiddleButton
{
get { return MouseEvent.MiddleButton; }
}
/**//// <summary>
/// 获取鼠标右键的当前状态。
/// </summary>
/// <returns>鼠标右键的当前状态,为 MouseButtonState.Pressed 或 MouseButtonState.Released。 没有默认值。</returns>
public MouseButtonState RightButton
{
get { return MouseEvent.RightButton; }
}
/**//// <summary>
/// 获取改变的按钮的状态。
/// </summary>
/// <returns>改变的按钮的状态。</returns>
public MouseButtonState ButtonState
{
get { return MouseEvent.ButtonState; }
}
/**//// <summary>
/// 获取改变状态的按钮。
/// </summary>
/// <returns>改变状态的按钮。</returns>
public MouseButton ChangedButton
{
get { return MouseEvent.ChangedButton; }
}
/**//// <summary>
/// 获取或设置一个值,该值指示路由事件在路由过程中的事件处理当前状态。(该属性当前不可用)
/// </summary>
public bool Handled
{ get; set; }
}
#endregion
MouseButton#region MouseButton
/**//// <summary>
/// 定义用于指定鼠标设备上的按钮的值。
/// </summary>
public enum MouseButton
{
/**//// <summary>
/// 鼠标左按钮。
/// </summary>
Left = 1,
/**//// <summary>
/// 鼠标中键。
/// </summary>
Middle = 2,
/**//// <summary>
/// 鼠标右按钮。
/// </summary>
Right = 4
}
#endregion
MouseButtonState#region MouseButtonState
/**//// <summary>
/// 指定鼠标按钮的可能状态。
/// </summary>
public enum MouseButtonState
{
/**//// <summary>
/// 该按钮处于释放状态。
/// </summary>
Released,
/**//// <summary>
/// 该按钮处于按下状态。
/// </summary>
Pressed
}
#endregion
}
声明:本代码可以无偿使用,如将本代码用于商业用途,必须经本人许可,否则视为侵权。