当前位置:  开发笔记 > 运维 > 正文

如何在TreeViewItem上为IsMouseOver创建WPF触发器不会影响moused-over控件的所有父项?

如何解决《如何在TreeViewItem上为IsMouseOver创建WPF触发器不会影响moused-over控件的所有父项?》经验,为你挑选了1个好方法。

我明白为什么会这样.父树型视图包括其子女的边界框的边框,所以当我将滑鼠移到一个树型视图,所有的父母在树上也鼠标滑过.我应该使用IsMouseOver以外的东西吗?



1> Kamiikoneko..:

http://blogs.msdn.com/mikehillberg/archive/2006/09/21/MyTreeViewHelperIsMouseDirectlyOverItem.aspx

这个链接解决了问题,我没有尝试原始来源的想法.

  

where local:MyTreeViewHelper.IsMouseDirectlyOverItem是附加属性

public static class MyTreeViewHelper
{
    //
    // The TreeViewItem that the mouse is currently directly over (or null).
    //
    private static TreeViewItem _currentItem = null;

    //
    // IsMouseDirectlyOverItem:  A DependencyProperty that will be true only on the 
    // TreeViewItem that the mouse is directly over.  I.e., this won't be set on that 
    // parent item.
    //
    // This is the only public member, and is read-only.
    //

    // The property key (since this is a read-only DP)
    private static readonly DependencyPropertyKey IsMouseDirectlyOverItemKey =
        DependencyProperty.RegisterAttachedReadOnly("IsMouseDirectlyOverItem",
                                            typeof(bool),
                                            typeof(MyTreeViewHelper),
                                            new FrameworkPropertyMetadata(null, new CoerceValueCallback(CalculateIsMouseDirectlyOverItem)));

    // The DP itself
    public static readonly DependencyProperty IsMouseDirectlyOverItemProperty =
        IsMouseDirectlyOverItemKey.DependencyProperty;

    // A strongly-typed getter for the property.
    public static bool GetIsMouseDirectlyOverItem(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsMouseDirectlyOverItemProperty);
    }

    // A coercion method for the property
    private static object CalculateIsMouseDirectlyOverItem(DependencyObject item, object value)
    {
        // This method is called when the IsMouseDirectlyOver property is being calculated
        // for a TreeViewItem.  

        if (item == _currentItem)
            return true;
        else
            return false;
    }

    //
    // UpdateOverItem:  A private RoutedEvent used to find the nearest encapsulating
    // TreeViewItem to the mouse's current position.
    //

    private static readonly RoutedEvent UpdateOverItemEvent = EventManager.RegisterRoutedEvent(
        "UpdateOverItem", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyTreeViewHelper));

    //
    // Class constructor
    //

    static MyTreeViewHelper()
    {
        // Get all Mouse enter/leave events for TreeViewItem.
        EventManager.RegisterClassHandler(typeof(TreeViewItem), TreeViewItem.MouseEnterEvent, new MouseEventHandler(OnMouseTransition), true);
        EventManager.RegisterClassHandler(typeof(TreeViewItem), TreeViewItem.MouseLeaveEvent, new MouseEventHandler(OnMouseTransition), true);

        // Listen for the UpdateOverItemEvent on all TreeViewItem's.
        EventManager.RegisterClassHandler(typeof(TreeViewItem), UpdateOverItemEvent, new RoutedEventHandler(OnUpdateOverItem));
    }


    //
    // OnUpdateOverItem:  This method is a listener for the UpdateOverItemEvent.  When it is received,
    // it means that the sender is the closest TreeViewItem to the mouse (closest in the sense of the tree,
    // not geographically).

    static void OnUpdateOverItem(object sender, RoutedEventArgs args)
    {
        // Mark this object as the tree view item over which the mouse
        // is currently positioned.
        _currentItem = sender as TreeViewItem;

        // Tell that item to re-calculate the IsMouseDirectlyOverItem property
        _currentItem.InvalidateProperty(IsMouseDirectlyOverItemProperty);

        // Prevent this event from notifying other tree view items higher in the tree.
        args.Handled = true;
    }

    //
    // OnMouseTransition:  This method is a listener for both the MouseEnter event and
    // the MouseLeave event on TreeViewItems.  It updates the _currentItem, and updates
    // the IsMouseDirectlyOverItem property on the previous TreeViewItem and the new
    // TreeViewItem.

    static void OnMouseTransition(object sender, MouseEventArgs args)
    {
        lock (IsMouseDirectlyOverItemProperty)
        {
            if (_currentItem != null)
            {
                // Tell the item that previously had the mouse that it no longer does.
                DependencyObject oldItem = _currentItem;
                _currentItem = null;
                oldItem.InvalidateProperty(IsMouseDirectlyOverItemProperty);
            }

            // Get the element that is currently under the mouse.
            IInputElement currentPosition = Mouse.DirectlyOver;

            // See if the mouse is still over something (any element, not just a tree view item).
            if (currentPosition != null)
            {
                // Yes, the mouse is over something.
                // Raise an event from that point.  If a TreeViewItem is anywhere above this point
                // in the tree, it will receive this event and update _currentItem.

                RoutedEventArgs newItemArgs = new RoutedEventArgs(UpdateOverItemEvent);
                currentPosition.RaiseEvent(newItemArgs);

            }
        }
    }
}

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有