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