2009-07-15 18 views

回答

4

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

這個環節解決了這個問題,我沒有嘗試初始源代碼的想法。

<Style TargetType="TreeViewItem"> 
    <Style.Triggers> 
     <Trigger Property="local:MyTreeViewHelper.IsMouseDirectlyOverItem" Value="True"> 
     <Setter Property="Background" Value="Green" /> 
     </Trigger> 
    </Style.Triggers> 
    </Style> 

,當地: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); 

      } 
     } 
    } 
} 
-1

這聽起來像是正確的事件。爲防止MouseOver事件,您可以做的一件事是檢查您的TreeViewItems的MouseOver事件。如果您的RoutedEventArgs.OriginalSource不等於父級,請手動返回並管理您的事件處理程序。

public void TreeViewItem_MouseOver(object sender, RoutedEventArgs e) 
{ 
    if (sender != e.OriginalSource) return; 
} 
+0

太糟糕了TreeViewItem沒有MouseOver事件... – RoelF 2010-09-16 08:16:29

+0

對不起。我在寫完這篇文章後意識到,我們使用了一個實現MouseOver的重寫的TreeViewItem類。如果確實有效,Mahop的解決方案將非常簡單。 – 2010-09-17 00:44:14

1

好了 - 我有你的問題,我已經浪費了幾乎一天解決它...... 所有你需要做的是從後面的代碼處理這件事。 例如:

在XAML:

<TreeViewItem Header="{Binding diskName}" 
Background="Transparent" Mouse.MouseEnter="changeBackground"> 

而在CS文件:

private void changeBackground(object sender, MouseEventArgs e) 
{ 
     TreeViewItem t = (TreeViewItem)sender; 
     t.Background = (SolidColorBrush)(new BrushConverter().ConvertFrom("#CCE8FF")); 
     e.Handled = false; 
} 

應該這樣做。祝你好運!

相關問題