.net 突出显示正在拖动的TreeView项目
在我的应用程序中,我有一个允许拖放的树状视图。我所有的功能都工作得很好,但是当它被拖过来时,我很难突出显示TreeViewItem。这是我的treeview项目的风格。拖动时IsMouseOver触发器不工作,因为拖动似乎会阻止其他鼠标事件。有人能帮我在拖动treeview项目时触发相同的边框更改吗.net 突出显示正在拖动的TreeView项目,.net,wpf,xaml,drag-and-drop,treeview,.net,Wpf,Xaml,Drag And Drop,Treeview,在我的应用程序中,我有一个允许拖放的树状视图。我所有的功能都工作得很好,但是当它被拖过来时,我很难突出显示TreeViewItem。这是我的treeview项目的风格。拖动时IsMouseOver触发器不工作,因为拖动似乎会阻止其他鼠标事件。有人能帮我在拖动treeview项目时触发相同的边框更改吗 <Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}"> <Setter Property
<Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton
x:Name="PART_Expander"
Style="{StaticResource ExpandCollapseToggleStyle}"
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
/>
<Border
x:Name="OuterBorder"
Grid.Column="1"
SnapsToDevicePixels="True"
BorderThickness="1"
CornerRadius="3"
BorderBrush="Transparent"
Background="Transparent"
>
<Border
x:Name="InnerBorder"
SnapsToDevicePixels="True"
BorderThickness="1"
CornerRadius="2"
BorderBrush="Transparent"
Background="Transparent"
>
<ContentPresenter
x:Name="PART_Content"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
/>
</Border>
</Border>
<ItemsPresenter
x:Name="PART_ItemsHost"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"
/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" SourceName="OuterBorder" Value="True">
<Setter TargetName="OuterBorder" Property="BorderBrush" Value="Blue" />
<Setter TargetName="OuterBorder" Property="Background" Value="Red" />
<Setter TargetName="InnerBorder" Property="BorderBrush" Value="White" />
</Trigger>
<MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
查看事件(可能还有DragEnter/DragLeave),而不是IsMouseOver。我正在为此使用附加属性,然后在我的xaml文件中使用该属性更改树状视图项的背景色:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace SKNotes.Utilities
{
/// <summary>
/// Implements an attached property used for styling TreeViewItems when
/// they're a possible drop target.
/// </summary>
public static class TreeViewDropHighlighter
{
#region private variables
/// <summary>
/// the TreeViewItem that is the current drop target
/// </summary>
private static TreeViewItem _currentItem = null;
/// <summary>
/// Indicates whether the current TreeViewItem is a possible
/// drop target
/// </summary>
private static bool _dropPossible;
#endregion
#region IsPossibleDropTarget
/// <summary>
/// Property key (since this is a read-only DP) for the IsPossibleDropTarget property.
/// </summary>
private static readonly DependencyPropertyKey IsPossibleDropTargetKey =
DependencyProperty.RegisterAttachedReadOnly(
"IsPossibleDropTarget",
typeof( bool ),
typeof( TreeViewDropHighlighter ),
new FrameworkPropertyMetadata( null,
new CoerceValueCallback( CalculateIsPossibleDropTarget ) ) );
/// <summary>
/// Dependency Property IsPossibleDropTarget.
/// Is true if the TreeViewItem is a possible drop target (i.e., if it would receive
/// the OnDrop event if the mouse button is released right now).
/// </summary>
public static readonly DependencyProperty IsPossibleDropTargetProperty = IsPossibleDropTargetKey.DependencyProperty;
/// <summary>
/// Getter for IsPossibleDropTarget
/// </summary>
public static bool GetIsPossibleDropTarget( DependencyObject obj )
{
return (bool)obj.GetValue( IsPossibleDropTargetProperty );
}
/// <summary>
/// Coercion method which calculates the IsPossibleDropTarget property.
/// </summary>
private static object CalculateIsPossibleDropTarget( DependencyObject item, object value )
{
if ( ( item == _currentItem ) && ( _dropPossible ) )
return true;
else
return false;
}
#endregion
/// <summary>
/// Initializes the <see cref="TreeViewDropHighlighter"/> class.
/// </summary>
static TreeViewDropHighlighter( )
{
// Get all drag enter/leave events for TreeViewItem.
EventManager.RegisterClassHandler( typeof( TreeViewItem ),
TreeViewItem.PreviewDragEnterEvent,
new DragEventHandler( OnDragEvent ), true );
EventManager.RegisterClassHandler( typeof( TreeViewItem ),
TreeViewItem.PreviewDragLeaveEvent,
new DragEventHandler( OnDragLeave ), true );
EventManager.RegisterClassHandler( typeof( TreeViewItem ),
TreeViewItem.PreviewDragOverEvent,
new DragEventHandler( OnDragEvent ), true );
}
#region event handlers
/// <summary>
/// Called when an item is dragged over the TreeViewItem.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="args">The <see cref="System.Windows.DragEventArgs"/> instance containing the event data.</param>
static void OnDragEvent( object sender, DragEventArgs args )
{
lock ( IsPossibleDropTargetProperty )
{
_dropPossible = false;
if ( _currentItem != null )
{
// Tell the item that previously had the mouse that it no longer does.
DependencyObject oldItem = _currentItem;
_currentItem = null;
oldItem.InvalidateProperty( IsPossibleDropTargetProperty );
}
if ( args.Effects != DragDropEffects.None )
{
_dropPossible = true;
}
TreeViewItem tvi = sender as TreeViewItem;
if ( tvi != null )
{
_currentItem = tvi;
// Tell that item to re-calculate the IsPossibleDropTarget property
_currentItem.InvalidateProperty( IsPossibleDropTargetProperty );
}
}
}
/// <summary>
/// Called when the drag cursor leaves the TreeViewItem
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="args">The <see cref="System.Windows.DragEventArgs"/> instance containing the event data.</param>
static void OnDragLeave( object sender, DragEventArgs args )
{
lock ( IsPossibleDropTargetProperty )
{
_dropPossible = false;
if ( _currentItem != null )
{
// Tell the item that previously had the mouse that it no longer does.
DependencyObject oldItem = _currentItem;
_currentItem = null;
oldItem.InvalidateProperty( IsPossibleDropTargetProperty );
}
TreeViewItem tvi = sender as TreeViewItem;
if ( tvi != null )
{
_currentItem = tvi;
tvi.InvalidateProperty( IsPossibleDropTargetProperty );
}
}
}
#endregion
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
命名空间SKNotes.Utilities
{
///
///在以下情况下实现用于设置TreeView项样式的附加属性:
///他们是可能的坠落目标。
///
公共静态类TreeViewer
{
#区域私有变量
///
///当前丢弃目标的TreeView项
///
私有静态TreeViewItem\u currentItem=null;
///
///指示当前TreeViewItem是否是可能的
///下降目标
///
私有静态boolu可能;
#端区
#区域是可能的下降目标
///
///IsPossibleDropTarget属性的属性键(因为这是只读DP)。
///
私有静态只读依赖项PropertyKey IsPossibleDropTargetKey=
DependencyProperty.RegisterAttacheOnly(
“IsPossibleDropTarget”,
类型(bool),
类型(TreeViewDropHighlighter),
新的FrameworkPropertyMetadata(空,
新的强制值回调(CalculateIsPossibleDropTarget));
///
///依赖项属性IsPossibleDropTarget。
///如果TreeViewItem是一个可能的丢弃目标(即,如果它将接收
///如果现在释放鼠标按钮,则显示OnDrop事件)。
///
公共静态只读DependencyProperty IsPossibleDropTargetProperty=IsPossibleDropTargetKey.DependencyProperty;
///
///IsPossibleDropTarget的Getter
///
公共静态bool GetIsPossibleDropTarget(DependencyObject obj)
{
返回(bool)对象GetValue(IsPossibleDropTargetProperty);
}
///
///计算IsPossibleDropTarget属性的强制方法。
///
私有静态对象CalculatesPossibledRopTarget(DependencyObject项,对象值)
{
如果((项目==\u当前项目)和(\u可能))
返回true;
其他的
返回false;
}
#端区
///
///初始化类。
///
静态树形荧光灯()
{
//获取TreeViewItem的所有拖放输入/离开事件。
RegisterClassHandler(typeof(treevieItem),
TreeViewItem.PreviewDragEnterEvent,
新DragEventHandler(OnDragEvent),正确;
RegisterClassHandler(typeof(treevieItem),
TreeViewItem.PreviewDragLeaveEvent,
新DragEventHandler(Ondragleef),正确;
RegisterClassHandler(typeof(treevieItem),
TreeViewItem.PreviewDragOverEvent,
新DragEventHandler(OnDragEvent),正确;
}
#区域事件处理程序
///
///在将项拖到TreeViewItem上时调用。
///
///发送者。
///包含事件数据的实例。
静态无效OnDragEvent(对象发送方、DragEventArgs参数)
{
锁(IsPossibleDropTargetProperty)
{
_dropposable=false;
如果(_currentItem!=null)
{
//告诉以前有鼠标的项目它不再有鼠标了。
DependencyObject oldItem=\u currentItem;
_currentItem=null;
oldItem.InvalidateProperty(IsPossibleDropTargetProperty);
}
if(args.Effects!=DragDropEffects.None)
{
_可能=真;
}
TreeViewItem tvi=发送方作为TreeViewItem;
如果(tvi!=null)
{
_currentItem=tvi;
//告诉该项重新计算IsPossibleDropTarget属性
_currentItem.InvalidateProperty(IsPossibleDropTargetProperty);
}
}
}
///
///当拖动光标离开Tr时调用
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="utils:TreeViewDropHighlighter.IsPossibleDropTarget" Value="True">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
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
static void OnDragDrop(object sender, DragEventArgs args)
{
lock (IsPossibleDropTargetProperty)
{
_dropPossible = false;
if (_currentItem != null)
{
_currentItem.InvalidateProperty(IsPossibleDropTargetProperty);
}
TreeViewItem tvi = sender as TreeViewItem;
if (tvi != null)
{
tvi.InvalidateProperty(IsPossibleDropTargetProperty);
}
}
}
EventManager.RegisterClassHandler(typeof(TreeViewItem),
TreeViewItem.PreviewDropEvent,
new DragEventHandler(OnDragDrop), true);