自定义鼠标

一)添加引入类(CursorEx.cs):

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.Linq;
using System.Diagnostics;
using System.Windows.Threading;

namespace CursorTest
{
    public class CursorEx
    {
        private static Popup _cursorPopup;
        private static DispatcherTimer _mouseLeaveTimer;
        private static object _syncRoot = new object();
        private static GeneralTransform _generalTransform;
        private static Point _mousePoint;
        private static UIElement _popupChild;
        private static FrameworkElement _shownElement;
        private static FrameworkElement _capturingElement;

        private static Popup CursorPopup
        {
            get
            {
                if (_cursorPopup == null)
                {
                    lock (_syncRoot)
                    {
                        if (_cursorPopup == null)
                        {
                            _cursorPopup = new Popup();
                            _cursorPopup.IsHitTestVisible = false;
                            _cursorPopup.IsOpen = true;
                        }
                    }
                }
                return _cursorPopup;
            }
        }

        /// <summary>
        /// MouseLeave後啟動
        /// </summary>
        private static DispatcherTimer MouseLeaveTimer
        {
            get
            {
                if (_mouseLeaveTimer == null)
                {
                    lock (_syncRoot)
                    {
                        if (_mouseLeaveTimer == null)
                        {
                            _mouseLeaveTimer = new DispatcherTimer();
                            _mouseLeaveTimer.Interval = TimeSpan.FromMilliseconds(10);
                            _mouseLeaveTimer.Tick += new EventHandler(OnMouseLeaveTimerTick);

                        }
                    }
                }
                return _mouseLeaveTimer;
            }
        }

        #region dependency property

        #region 自定義鼠標
        public static UIElement GetCustomCursor(DependencyObject obj) { return (UIElement)obj.GetValue(CustomCursorProperty); }

        public static void SetCustomCursor(DependencyObject obj, UIElement value) { obj.SetValue(CustomCursorProperty, value); }

        public static readonly DependencyProperty CustomCursorProperty =
            DependencyProperty.RegisterAttached("CustomCursor", typeof(FrameworkElement), typeof(CursorEx), new PropertyMetadata(OnCursorChanged));
        #endregion

        #region 是否使用默認鼠標
        public static bool GetUseOriginalCursor(DependencyObject obj)
        {
            return (bool)obj.GetValue(UseOriginalCursorProperty);
        }

        public static void SetUseOriginalCursor(DependencyObject obj, bool value)
        {
            obj.SetValue(UseOriginalCursorProperty, value);
        }

        public static readonly DependencyProperty UseOriginalCursorProperty =
            DependencyProperty.RegisterAttached("UseOriginalCursor", typeof(bool), typeof(CursorEx), new PropertyMetadata(OnUseOriginalCursorChanged));
        #endregion

        #region 本來的鼠標
        private static Cursor GetOriginalCursor(DependencyObject obj)
        {
            return (Cursor)obj.GetValue(OriginalCursorProperty);
        }

        private static void SetOriginalCursor(DependencyObject obj, Cursor value)
        {
            obj.SetValue(OriginalCursorProperty, value);
        }

        public static readonly DependencyProperty OriginalCursorProperty =
            DependencyProperty.RegisterAttached("OriginalCursor", typeof(Cursor), typeof(CursorEx), null);
        #endregion

        #endregion

        #region 響應事件

        private static void OnUseOriginalCursorChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            FrameworkElement element = obj as FrameworkElement;
            if (element != null)
                SetCusorToUIElement(element);
        }


        private static void OnCursorChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            FrameworkElement element = obj as FrameworkElement;
            if (element != null)
                SetCusorToUIElement(element);
        }

        private static void OnMouseMove(object sender, MouseEventArgs e)
        {
            FrameworkElement element = sender as FrameworkElement;
            _generalTransform = element.TransformToVisual(Silverlight.App.Current.RootVisual);
            OnMouseMove(element, _generalTransform.Transform(e.GetPosition(element)));
        }


        private static void OnMouseLeave(object sender, MouseEventArgs e)
        {
            var popup = CursorPopup;
            FrameworkElement element = sender as FrameworkElement;
            var child = GetCustomCursor(element);
            if (child != null)
                child.Visibility = Visibility.Collapsed;

            if (_capturingElement == element)
                MouseLeaveTimer.Start();
            else
                _shownElement = null;
        }

        private static void OnMouseLeaveTimerTick(object sender, EventArgs e)
        {
            if (_capturingElement == null || CheckIsCapturing(_capturingElement) == false)
            {
                MouseLeaveTimer.Stop();
                _shownElement = null;
                UpdateCurrentChild();
            }
        }
        #endregion


        private static void SetCusorToUIElement(FrameworkElement element)
        {
            var customCurosr = GetCustomCursor(element);
            var userOriginalCursor = GetUseOriginalCursor(element);
            if (customCurosr != null || userOriginalCursor)
            {
                if (customCurosr != null)
                {
                    customCurosr.IsHitTestVisible = false;
                    if (_shownElement == element && CursorPopup.Child != null)
                    {
                        customCurosr.Visibility = CursorPopup.Child.Visibility;
                        CursorPopup.Child = customCurosr;
                    }
                }
                if (userOriginalCursor == false)
                    element.Cursor = Cursors.None;
                DetachEvent(element);
                AttachEvent(element);
                if (_mousePoint != null && VisualTreeHelper.FindElementsInHostCoordinates(_mousePoint, element).Contains(element))
                    OnMouseMove(element, _mousePoint);
            }
            else
            {
                SetIsHandeld(element, false);
                element.Cursor = GetOriginalCursor(element);
                UpdateCurrentChild();
            }

            if (GetOriginalCursor(element) == null && element.Cursor != Cursors.None)
                SetOriginalCursor(element, element.Cursor);
        }

        private static void AttachEvent(FrameworkElement element)
        {
            element.MouseLeave += new MouseEventHandler(OnMouseLeave);
            element.MouseMove += new MouseEventHandler(OnMouseMove);
        }

        private static void DetachEvent(FrameworkElement element)
        {
            element.MouseLeave -= new MouseEventHandler(OnMouseLeave);
            element.MouseMove -= new MouseEventHandler(OnMouseMove);
        }


        private static bool CheckIsHandled(FrameworkElement element)
        {
            if (_shownElement == element)
                return false;
            FrameworkElement parent = _shownElement;
            while (parent != null && parent != element)
                parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
            if (parent != null)
                return true;
            else
                return false;
        }

        private static void SetIsHandeld(FrameworkElement element, bool value)
        {
            if (value)
                _shownElement = element;
            else
            {
                if (_shownElement == element)
                    _shownElement = null;
                DetachEvent(element);
            }
        }

        private static void OnMouseMove(FrameworkElement element, Point mousePoint)
        {
            _mousePoint = mousePoint;
            if (element == null || CheckIsHandled(element))
                return;
            SetIsHandeld(element, true);
            _popupChild = GetCustomCursor(element);

            if (_popupChild != CursorPopup.Child)
                CursorPopup.Child = _popupChild;
            if (_popupChild == null)
                return;
            if (_popupChild.Visibility != Visibility.Visible)
                _popupChild.Visibility = Visibility.Visible;
            CursorPopup.HorizontalOffset = _mousePoint.X;
            CursorPopup.VerticalOffset = _mousePoint.Y;

            if (CheckIsCapturing(element))
                _capturingElement = element;
            else if (_capturingElement == element)
                _capturingElement = null;
            GetToppestElement(_mousePoint);
        }


        private static void UpdateCurrentChild()
        {
            if (_mousePoint == null)
                return;
            var pointElement = GetToppestElement(_mousePoint);
            if (pointElement == null)
                CursorPopup.Child = null;
            else
                OnMouseMove(pointElement, _mousePoint);
        }

        private static FrameworkElement GetToppestElement(Point point)
        {
            var elements = VisualTreeHelper.FindElementsInHostCoordinates(point, Silverlight.App.Current.RootVisual);
            return elements.Where(es => (es is FrameworkElement)
                && (GetCustomCursor(es as FrameworkElement) != null || GetUseOriginalCursor(es as FrameworkElement) == true))
                .ElementAtOrDefault(0) as FrameworkElement;
        }


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


}

 

二)定制相关的鼠标界面,一个独立的xaml:

<UserControl x:Class="Silverlight.ZoomOutCursor"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

    <Grid>
        <Image Source="/Silverlight;component/Images/sx.png" Width="20" Height="20" />

    </Grid>
</UserControl>

 

三)引用XAML的类,并且调用:

 FrameworkElement zoomin =new  ZoomInCursor();

   CursorEx.SetCustomCursor(MyMap,zoomin);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值