Tôi hiểu tại sao điều này xảy ra. Hộp giới hạn của một TreeViewItem cha mẹ bao gồm các hộp giới hạn của trẻ em, vì vậy khi tôi được gắn trên một TreeViewItem, tất cả các bậc cha mẹ của nó trong cây cũng được kết hợp. Có cái gì ngoài IsMouseOver tôi nên sử dụng?Làm cách nào để tôi kích hoạt Trình kích hoạt WPF cho IsMouseOver trên TreeViewItem KHÔNG ảnh hưởng đến tất cả các bậc cha mẹ của điều khiển được kiểm soát?
Trả lời
http://blogs.msdn.com/mikehillberg/archive/2006/09/21/MyTreeViewHelperIsMouseDirectlyOverItem.aspx
liên kết này đã giải quyết được vấn đề, tôi không cố ý tưởng Nguồn gốc.
<Style TargetType="TreeViewItem">
<Style.Triggers>
<Trigger Property="local:MyTreeViewHelper.IsMouseDirectlyOverItem" Value="True">
<Setter Property="Background" Value="Green" />
</Trigger>
</Style.Triggers>
</Style>
nơi địa phương: MyTreeViewHelper.IsMouseDirectlyOverItem được gắn sở hữu
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);
}
}
}
}
Điều đó nghe giống như sự kiện phù hợp. Một điều bạn có thể làm để ngăn chặn các sự kiện MouseOver là kiểm tra các sự kiện MouseOver cho TreeViewItems của bạn. Nếu RoutedEventArgs.OriginalSource của bạn không bằng cha mẹ, chỉ cần trả về và quản lý trình xử lý sự kiện của bạn theo cách thủ công.
public void TreeViewItem_MouseOver(object sender, RoutedEventArgs e)
{
if (sender != e.OriginalSource) return;
}
quá tệ không có sự kiện MouseOver cho TreeViewItem ... – RoelF
Xin lỗi về điều đó. Tôi thực sự nhận ra sau khi viết điều này mà chúng tôi làm việc với một lớp TreeViewItem ghi đè mà thực hiện MouseOver. Nếu nó thực sự hoạt động, giải pháp của Mahop sẽ đơn giản hơn. –
Ok - Tôi có vấn đề của bạn và tôi đã lãng phí gần một ngày giải quyết nó ... Tất cả bạn cần làm là để chăm sóc điều đó từ mã phía sau. Ví dụ:
Trong XAML:
<TreeViewItem Header="{Binding diskName}"
Background="Transparent" Mouse.MouseEnter="changeBackground">
Và trong file cs:
private void changeBackground(object sender, MouseEventArgs e)
{
TreeViewItem t = (TreeViewItem)sender;
t.Background = (SolidColorBrush)(new BrushConverter().ConvertFrom("#CCE8FF"));
e.Handled = false;
}
Điều đó sẽ làm điều đó. Chúc may mắn!
Nếu cách này giải quyết được vấn đề của bạn, vui lòng đánh dấu nó là câu trả lời của bạn. – jpierson