Этот пост просто портирует удивительный ответ Стефана выше на VB, для тех из нас, кто работает в этих границах; Мне нечего предложить, кроме как надеяться, что я ничего не испортил. Похоже, у меня работает:
Namespace SKNotes.Utilities
''' <summary>
''' Implements an attached property used for styling TreeViewItems when
''' they are a possible drop target.
''' </summary>
Public Class TreeViewDropHighlighter
''' <summary>
''' The TreeViewItem that is the current drop target
''' </summary>
Private Shared _CurrentItem As TreeViewItem = Nothing
''' <summary>
''' Indicates whether the current TreeView Item is a possible drop target
''' </summary>
''' <remarks></remarks>
Private Shared _DropPossible As Boolean
''' <summary>
''' Property Key (since this is a read only DP) for the IsPossibleDropTarget property.
''' </summary>
''' <remarks></remarks>
Private Shared ReadOnly IsPossibleDropTargetKey As DependencyPropertyKey = _
DependencyProperty.RegisterAttachedReadOnly _
( _
"IsPossibleDropTarget", _
GetType(Boolean), _
GetType(TreeViewDropHighlighter), _
New FrameworkPropertyMetadata(Nothing, _
New CoerceValueCallback(AddressOf CalculateIsPossibleDropTarget)
)
)
''' <summary>
''' Dependency Property IsPossibleDropTarget.
''' Is true if the TreeViewItem is a possible drop target (ie, if it would receive the
''' OnDrop even if the mouse button is release right now).
''' </summary>
''' <remarks></remarks>
Public Shared ReadOnly IsPossibleDropTargetProperty As DependencyProperty = IsPossibleDropTargetKey.DependencyProperty
''' <summary>
''' Getter for IsPossibleDropTarget
''' </summary>
Public Shared Function GetIsPossibleDropTarget(ByVal obj As DependencyObject) As Boolean
Return CBool(obj.GetValue(IsPossibleDropTargetProperty))
End Function
''' <summary>
''' Coercion method which calculates the IsPossibleDropTarget property
''' </summary>
Private Shared Function CalculateIsPossibleDropTarget(item As DependencyObject, value As Object) As Object
If item.Equals(_CurrentItem) And _
_DropPossible Then
Return True
Else
Return False
End If
End Function
''' <summary>
''' Initializes the TreeViewDropHighlighter class
''' </summary>
Shared Sub New()
EventManager.RegisterClassHandler(GetType(TreeViewItem), _
TreeViewItem.PreviewDragEnterEvent, _
New DragEventHandler(AddressOf OnDragEvent), True)
EventManager.RegisterClassHandler(GetType(TreeViewItem), _
TreeViewItem.PreviewDragLeaveEvent,
New DragEventHandler(AddressOf OnDragLeave), True)
EventManager.RegisterClassHandler(GetType(TreeViewItem), _
TreeViewItem.PreviewDragOverEvent, _
New DragEventHandler(AddressOf OnDragEvent), True)
End Sub
''' <summary>
''' Called when an item is dragged over the TreeView Item
''' </summary>
''' <param name="sender">The sender</param>
''' <param name="args">The System.Windows.DragEventArgs instance containing the event data</param>
''' <remarks></remarks>
Shared Sub OnDragEvent(sender As Object, args As DragEventArgs)
SyncLock (IsPossibleDropTargetProperty)
_DropPossible = False
If Not IsNothing(_CurrentItem) Then
'Tell the item that previously had the mouse that it no longer does.
Dim OldItem As DependencyObject = _CurrentItem
_CurrentItem = Nothing
OldItem.InvalidateProperty(IsPossibleDropTargetProperty)
End If
If args.Effects <> DragDropEffects.None Then
_DropPossible = True
End If
Dim tvi As TreeViewItem = CType(sender, TreeViewItem)
If Not IsNothing(tvi) Then
_CurrentItem = tvi
'Tell that item to recalculate the IsPossibleDropTarget property
_CurrentItem.InvalidateProperty(IsPossibleDropTargetProperty)
End If
End SyncLock
End Sub
Shared Sub OnDragLeave(sender As Object, args As DragEventArgs)
SyncLock (IsPossibleDropTargetProperty)
_DropPossible = False
If Not IsNothing(_CurrentItem) Then
'Tell the item that previously had the mouse that it no longer does
Dim OldItem As DependencyObject = _CurrentItem
_CurrentItem = Nothing
OldItem.InvalidateProperty(IsPossibleDropTargetProperty)
End If
Dim tvi As TreeViewItem = CType(sender, TreeViewItem)
If Not IsNothing(tvi) Then
_CurrentItem = tvi
tvi.InvalidateProperty(IsPossibleDropTargetProperty)
End If
End SyncLock
End Sub
End Class
Конечное пространство имен