How can we activate a WPF trigger in XAML when a drag operation is occurring?
We're looking for a way to base a WPF trigger in XAML on whether or not we're in a drag-drop operation. Depending on if we are or not, we want different hovering behaviors which is why this is needed.
The only way I can think of is to handle the drag start and end events and manually track the state, but that requires a code-behind, not pure XAML. Plus it seems like complete overkill, especially since we'd have to do it on every potential drop target which is a real pain.
So is there an easy w开发者_Go百科ay to say 'Hey... I'm in a drag-drop operation so make this trigger active' or am I out of luck here?
Update
To clarify what we are trying to do, currently in pure XAML, you can create a style, then set a style trigger to examine the IsMouseOver property to say, draw a background highlight. Well, we want to do this, but we want to say if 'IsMouseOver' is true and if IsDragging = true then apply this trigger.
I've just had this problem, my solution consists of using an attached property that supplies the missing IsDragging
:
Define the attached Property
public static readonly DependencyProperty IsDraggingProperty = DependencyProperty.RegisterAttached ( "IsDragging", typeof(bool), typeof(ClassContainingThisProperty), new UIPropertyMetadata(false) ); public static bool GetIsDragging(DependencyObject source) { return (bool)source.GetValue(IsDraggingProperty); } public static void SetIsDragging(DependencyObject target, bool value) { target.SetValue(IsDraggingProperty, value); }
Create this extension methods to help you set the Property
public static TParent FindParent<TParent>(this DependencyObject child) where TParent : DependencyObject { DependencyObject current = child; while(current != null && !(current is TParent)) { current = VisualTreeHelper.GetParent(current); } return current as TParent; } public static void SetParentValue<TParent>(this DependencyObject child, DependencyProperty property, object value) where TParent : DependencyObject { TParent parent = child.FindParent<TParent>(); if(parent != null) { parent.SetValue(property, value); } }
Handle DragDrop events according to the Control used (e.g. ListView), to set the attached property on the elements.
private void OnDragEnter(object sender, DragEventArgs e) { DependencyObject source = e.OriginalSource as DependencyObject; if (source != null) { source.SetParentValue<ListViewItem>(ClassContainingTheProperty.IsDraggingProperty, true); } } private void OnDragLeave(object sender, DragEventArgs e) { DependencyObject source = e.OriginalSource as DependencyObject; if(source != null) { source.SetParentValue<ListViewItem>(ClassContainingTheProperty.IsDraggingProperty, false); } } private void OnDrop(object sender, DragEventArgs e) { DependencyObject source = e.OriginalSource as DependencyObject; if(source != null) { source.SetParentValue<ListViewItem>(ClassContainingTheProperty.IsDraggingProperty, false); } }
Use the Property in your Trigger
<ControlTemplate TargetType="{x:Type ListViewItem}"> <ControlTemplate.Triggers> <Trigger Property="namespace:ClassContainingTheProperty.IsDragging" Value="True"> <Setter Property="Background" Value="White" /> <Setter Property="BorderBrush" Value="Black" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>
I've only ever seen drag-drop implemented with event handlers, so I think you're out of luck. I suggest you create your own dependency property to indicate a drag drop in progress.
if it is a real DragDrop event just watch for the DragOver event...
<EventTrigger RoutedEvent="DragOver">
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Fill.Color">
<ColorAnimation From="White" To="Black" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
精彩评论