专栏首页dino.c的专栏Silverlight自定义鼠标

Silverlight自定义鼠标

  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实现的。

  使用很简单:

代码 
 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可以捕获鼠标,所以可以用下面这个方法检测是否已经捕获了鼠标:

代码 
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;
            }
        }
3,VisualTreeHelper.FindElementsInHostCoordinates(Point, UIElement): 检索一组对象,这些对象位于某一对象的坐标空间的指定点内。

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

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

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

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

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [WPF自定义控件库] 关于ScrollViewr和滚动轮劫持(scroll-wheel-hijack)

    所有代码就这么多,这个ExtendedScrollViewer 只是用来解决滚动轮劫持(scroll-wheel-hijack)的问题。所谓的滚动轮劫持,简单来...

    dino.c
  • [UWP]如何使用Fluent Design System (下)

    FDS最常见的问题之一是如何与Fall Creators Update之前的版本兼容,其实做起来也挺简单的,ColorfulBox就实现了Creators Up...

    dino.c
  • [UWP]占领标题栏

    每一个有理想的UWP应用都会打标题栏的主意,尤其当微软提供 将 Acrylic 扩展到标题栏 这个功能后,大部分Windows 10的原生应用都不乖了,纷纷占领...

    dino.c
  • 数据分析Excel技能之移动某行

    单击第3行的「行标」选中第3行,把鼠标指向第3行的「下边缘」,当指针变为一个「小手」形状时,按住鼠标左键拖动鼠标便可以拖动第三行到某一个位置。

    有福
  • UE4新手编程之创建C++项目

     虚幻4中常用的按键和快捷键 虚幻4中有一些按键和快捷键很常用,牢记它们并运动到实际的项目开发中,将会大大地提高你的工作效率和使得工作更简便快捷。下面将列举它们...

    用户1198337
  • 用Mockplus教你使用属性面板的设置交互状态

    使用Mockplus软件有段时间了,期间有很多使用者问我组件的设置交互状态怎么用(当然有很多人看了都会用),我就有想把怎样使用设置交互状态的方法记录下来,供初学...

    奔跑的小鹿
  • js鼠标事件

    PS:鼠标移动(onmousemove)和鼠标移入(onmouseover)区别:移动事件指鼠标只要移动就产生事件,移入事件需要移入到指定的对象内才执行事件

    十月梦想
  • 突破极验验证的验证码

    极验验证验证码类似于这样的 http://www.geetest.com/exp_embed

    冰封一夏
  • 使用这些 HTTP 头保护 Web 应用

    目前,浏览器已经实现了大量与安全相关的头文件,使攻击者更难利用漏洞。接下来的讲解它们的使用方式、它们防止的攻击类型以及每个头后面的一些历史。

    Fundebug
  • 基于HTML5 Canvas和jQuery 的画图工具的实现

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.c...

    亦山

扫码关注云+社区

领取腾讯云代金券