Silverlight自定义鼠标

本文介绍如何在Silverlight中实现自定义鼠标样式,包括使用Popup显示内容、捕获鼠标及利用VisualTreeHelper检索对象等关键技术。此外还讨论了自定义鼠标在不同控件上的应用限制。

  Silverlight不提供自定义鼠标,它只提供了默认的几种鼠标样式:

  http://msdn.microsoft.com/zh-cn/library/system.windows.input.cursor(VS.95).aspx

  如果需要自定义鼠标样式,通常的做法是设置Cursor=Cursors.None,然后在最顶层放一张图片,在MouseMove事件中移动这张图片。至于调用方法,用附加属性比较方便:

 

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

 

 

  要实现自定义鼠标,需要先理解以下几种概念:

1,Popup: Silverlight 内容区域的界限之内、现有 Silverlight 内容之上显示内容。

  Popup这东西现在是很少用了,不过在Silverlight 2 RC以前是没有ComboBox的,那时候通常就用Popup自己做一个ComboBox。现在有了ComboBox,我们也就不必在自己写了,不过ComboBox的下拉菜单还是用Popup实现的。

  使用很简单:

 

ExpandedBlockStart.gif 代码
  private   void  OnMouseMove( object  sender, MouseEventArgs e)
 {
      FrameworkElement element 
=  sender  as  FrameworkElement;
      GeneralTransform generalTransform 
=  element.TransformToVisual(App.Current.RootVisual);
      Point point 
= generalTransform.Transform(e.GetPosition(element));
      Popup  pp 
=  point.X;
      pp.VerticalOffset 
=  _ point.Y;
      
// pp.Child=…….
      pp.IsOpen  = True;
  }

 

 

 

2, public bool CaptureMouse():将鼠标捕获设置为 UIElement 

  这个方法通常用在鼠标拖动,譬如在TextBox中拖动选中文字,或是拖动滚动条。在鼠标按下时执行这个方法,如果没有其它元素已经捕获了鼠标,则返回True,并且无论鼠标移动到哪里都可以接收鼠标输入,直到执行ReleaseMouseCapture()释放鼠标。

  当捕获了鼠标后,即使鼠标在其他控件上移动,那些控件都是没有反应的。而且鼠标样式还是捕获鼠标的FrameworkElement的样式(具体可参考Window中拖动边框修改窗口大小时的鼠标样式,拖动时无论移动到哪里,鼠标样式都是不变的)。

  因为同一时间只有一个FrameworkElement可以捕获鼠标,所以可以用下面这个方法检测是否已经捕获了鼠标:

 

ExpandedBlockStart.gif 代码
private   static   bool  CheckIsCapturing(FrameworkElement element)
        {
            
bool  isRootCapturingMouse  =  App.Current.RootVisual.CaptureMouse();
            App.Current.RootVisual.ReleaseMouseCapture();
            
if  (isRootCapturingMouse)
                
return   false ;
            
else
            {
                
if  (element.CaptureMouse())
                    
return   true ;
                
else
                    
return   false ;
            }
        }

 

 

 

3VisualTreeHelper.FindElementsInHostCoordinates(Point, UIElement): 检索一组对象,这些对象位于某一对象的坐标空间的指定点内。

  依序返回点中的UIElement及其Parent,一直到Parent==Null为止,其结果是一个IEnumerable<UIElement>。因为MouseEventArgs不具备Handled属性,所以在VisualTree上同一个区域的所有UIElement都会发生MouseMove事件,其次序是从上层直到下层。如果有一个Grid,里面包含一个Border,且GridBorder都设定了自定义鼠标,则会发生冲突,所以我使用了这个方法获取最上层并且设定了自定义鼠标的UIElement 

 

 

  具体内容不一一列出,最终效果如下(借用了这里的鼠标样式http://www.cnblogs.com/gnielee/archive/2010/01/15/1648832.html):

 

   获取 Microsoft Silverlight

 

  效率好像不怎么好,而且有两个问题:

  1TextBox的鼠标是设置在ControlTemplate中的某个元素,所以在外面设Cursor=Cursors.None是没用的,而且拖动选中文字时会捕获鼠标,这也是我们不能控制的,为免同时出现默认的鼠标和自定义鼠标,特地多添加了一个附加属性“UseOriginalCursor”,设为True时只使用默认鼠标。不过,其实也是可以定义TextBox ControlTemplate改变里面的鼠标样式的。

   2:自定义鼠标出现的地点基于附加了CustomCursor属性的UIElementMouseMove事件时产生的Point,所以如果鼠标没有在CustomCursor上移动过,自定义鼠标就不会出现。

 

源代码:http://files.cnblogs.com/dino623/CursorTest100326.rar

转载于:https://www.cnblogs.com/dino623/archive/2010/04/01/1702260.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值