热门:网页模板.net视频教程JQueryMVCjsonExtJs源码示例三级联动JQuery菜单
您现在的位置:.Net中文社区>> Silverlight>>正文内容

Silverlight自定义鼠标【附源码】

发布时间:2010年04月02日点击数: 佚名

Silverlight不提供自定义鼠标,它只提供了默认的几种鼠标样式:
  http://msdn.microsoft.com/zh-cn/library/system.windows.input.cursor(VS.95).aspx
  如果需要自定义鼠标样式,通常的做法是设置Cursor=Cursors.None,然后在最顶层放一张图片,在MouseMove事件中移动这张图片。至于调用方法,用附加属性比较方便: 【源码下载

  1. <local:CursorEx.CustomCursor> 
  2.    <Image Source="images/arrow.png" Height="15" Width="15"/> 
  3. </local:CursorEx.CustomCursor> 

  要实现自定义鼠标,需要先理解以下几种概念:
1,Popup: 在 Silverlight 内容区域的界限之内、现有 Silverlight 内容之上显示内容。
  Popup这东西现在是很少用了,不过在Silverlight 2 RC以前是没有ComboBox的,那时候通常就用Popup自己做一个ComboBox。现在有了ComboBox,我们也就不必在自己写了,不过ComboBox的下拉菜单还是用Popup实现的。
  使用很简单:

  1. private void OnMouseMove(object sender, MouseEventArgs e) 
  2.  { 
  3.       FrameworkElement element = sender as FrameworkElement; 
  4.       GeneralTransform generalTransform = element.TransformToVisual(App.Current.RootVisual); 
  5.       Point point =generalTransform.Transform(e.GetPosition(element)); 
  6.       Popup  pp = point.X; 
  7.       pp.VerticalOffset = _ point.Y; 
  8.       //pp.Child=……. 
  9.       pp.IsOpen =True; 
  10.   } 

2, public bool CaptureMouse():将鼠标捕获设置为 UIElement。
  这个方法通常用在鼠标拖动,譬如在TextBox中拖动选中文字,或是拖动滚动条。在鼠标按下时执行这个方法,如果没有其它元素已经捕获了鼠标,则返回True,并且无论鼠标移动到哪里都可以接收鼠标输入,直到执行ReleaseMouseCapture()释放鼠标。
  当捕获了鼠标后,即使鼠标在其他控件上移动,那些控件都是没有反应的。而且鼠标样式还是捕获鼠标的FrameworkElement的样式(具体可参考Window中拖动边框修改窗口大小时的鼠标样式,拖动时无论移动到哪里,鼠标样式都是不变的)。
  因为同一时间只有一个FrameworkElement可以捕获鼠标,所以可以用下面这个方法检测是否已经捕获了鼠标:

  1. private static bool CheckIsCapturing(FrameworkElement element) 
  2.         { 
  3.             bool isRootCapturingMouse = App.Current.RootVisual.CaptureMouse(); 
  4.             App.Current.RootVisual.ReleaseMouseCapture(); 
  5.             if (isRootCapturingMouse) 
  6.                 return false
  7.             else 
  8.             { 
  9.                 if (element.CaptureMouse()) 
  10.                     return true
  11.                 else 
  12.                     return false
  13.             } 
  14.         } 

3,VisualTreeHelper.FindElementsInHostCoordinates(Point, UIElement): 检索一组对象,这些对象位于某一对象的坐标空间的指定点内。
  依序返回点中的UIElement及其Parent,一直到Parent==Null为止,其结果是一个IEnumerable<UIElement>。因为MouseEventArgs不具备Handled属性,所以在VisualTree上同一个区域的所有UIElement都会发生MouseMove事件,其次序是从上层直到下层。如果有一个Grid,里面包含一个Border,且Grid和Border都设定了自定义鼠标,则会发生冲突,所以我使用了这个方法获取最上层并且设定了自定义鼠标的UIElement。

效果图如下:

效率好像不怎么好,而且有两个问题:
  1:TextBox的鼠标是设置在ControlTemplate中的某个元素,所以在外面设Cursor=Cursors.None是没用的,而且拖动选中文字时会捕获鼠标,这也是我们不能控制的,为免同时出现默认的鼠标和自定义鼠标,特地多添加了一个附加属性“UseOriginalCursor”,设为True时只使用默认鼠标。不过,其实也是可以定义TextBox的 ControlTemplate改变里面的鼠标样式的。
  2:自定义鼠标出现的地点基于附加了CustomCursor属性的UIElement在MouseMove事件时产生的Point,所以如果鼠标没有在CustomCursor上移动过,自定义鼠标就不会出现。

本站热点业务

更多模板/案例展示

关于我们 | 联系我们 | 团队日志 | 网站地图 | 网站合作