This topic provides an overview of Intersoft ClientUI Drag-drop Framework. Drag-and-drop commonly refers to a method of user interface (UI) interaction that involves using a mouse to select one or more objects, dragging these objects over some desired drop target in the UI, and dropping them.
This topic contains the following sections:
- Drag and Drop Support in ClientUI
- Drag and Drop Panel
- Drag and Drop Events
- Working with Data Objects
Drag and Drop Support in ClientUI
The drag-drop framework in ClientUI provides a comprehensive library to easily add drag and drop capability to any UI Elements within Silverlight or WPF application.
Drag-and-drop operations typically involve two parties: a drag source from which the dragged object originates and a drop target which receives the dropped object. Using the drag-drop framework available in ClientUI, you can make an UIElement dragable by simply attaching a behavior to the UIElement or using API to initiate the drag-drop session.
Making an UIElement Dragable using DragDropBehavior
To make an UIElement dragable, you attach a DragDropBehavior to that particular elements as shown in the XAML code below.
XAML | ![]() |
---|---|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <i:Interaction.Behaviors> <Intersoft:DragDropBehavior/> </i:Interaction.Behaviors> <Image Source="folder.png" Height="64" Width="64"/> <TextBlock Text="My Archive" HorizontalAlignment="Center" VerticalAlignment="Center"/> </StackPanel> |
In the above sample, the DragDropBehavior is attached to a StackPanel that has an image and a text element.
When you dragged the StackPanel, the StackPanel is not moved from its original place. The actual element being moved is a shadow object that represents the current dragable object. This shadow object serves as an indicator where the object is currently dragged into. If it is dropped to a non droppable target, there will be an animation to indicate the shadow object being returned to the original position. To learn more how to customize the shadow object, see How to: Customize Drag Shadow Object.
The side effect of this concept is that you can start the drag-drop operation by dragging any elements within the StackPanel, which might not always be desirable. To make only certain elements dragable, you attach a DragDropPointBehavior to the desired dragable element which is the children element of the StackPanel.
The following code shows how you can limit the drag source to an Image element.
XAML | ![]() |
---|---|
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top"> <i:Interaction.Behaviors> <Intersoft:DragDropBehavior IsDragable="False"/> </i:Interaction.Behaviors> <Image Source="folder.png" Height="64" Width="64"> <i:Interaction.Behaviors> <Intersoft:DragDropPointBehavior IsDragable="True"/> </i:Interaction.Behaviors> </Image> <TextBlock Text="My Archive" HorizontalAlignment="Center" VerticalAlignment="Center"/> </StackPanel> |
Customizing Drag Effects
When an object is being dragged, the source object is still displayed as the shadow object appears. This behavior can further customized by modifying the DragEffect property. There are three types of DragEffect that you can select:
-
Copy (Default)
This effect leaves the source object displayed when the shadow object appears. This effect gives a hint that the object is being copied.
-
Link
This effect leaves the source object displayed when the shadow object appears, the same effect as Copy with different tooltip. This effect gives a hint that the object is being linked.
-
Move
This effect collapsed the source object, allowing the panel that host the source object to re-adjust when the shadow object appears. This effect gives a hint that the source object is moved.
-
Space
This effect set the source object opacity to 0, when the shadow object appears. This effect give a hint that the source object is moved by leaving its space.
Customizing Initial Tooltip
Each DragEffect comes with predefined tooltip image and text that indicates the drag action.
- DragEffect = Copy, shows copy icon and "Copy" tooltip
- DragEffect = Link, shows link icon and "Link" tooltip
- DragEffect = Move, shows move icon and "Move" tooltip
- DragEffect = Space, shows move icon and "Move" tooltip
You can customize the tooltip by modifying the TooltipIcon and TooltipText properties as shown below.
Sample Code | ![]() |
---|---|
<Border Height="116" Width="100"> <i:Interaction.Behaviors> <Intersoft:DragDropBehavior TooltipIcon="cursor_link.png" TooltipText="Link"/> </i:Interaction.Behaviors> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Image Source="folder2.png"/> <TextBlock Grid.Row="1" Text="My Archive" HorizontalAlignment="Center"/> </Grid> </Border> |
You can also customize the offset position of the tooltip using the TooltipOffset property, or change the TooltipLatency property to enhance the user experience aspects.
Customizing Tooltip Latency
When the drag is initiated, the tooltip only shows the tooltip icon, it will then display the tooltip text until a certain time span has elapsed which is determined by the TooltipLatency property. After the text is shown, it will remain visible and will be updated accordingly to user modification.
Making an UIElement Dragable using provided API
To make an UIElement dragable, you can also use the provided API. The API to drag the object is DragDrop.DoDragDrop method. You can also use the ISDragDrop.DoDragDrop method, since this method is equivalent with DragDrop.DoDragDrop method.
The DragDrop.DoDragDrop is provided to enable unified shared code base with WPF, allowing you to easily migrate your existing WPF application that used WPF's Drag-drop API to the Silverlight application without major changes.
To learn how to make an UIElement dragable using API, see How-to: Drag an UIElement using API.
Making an UIElement Droppable
To make an UIElement droppable, you can choose one of the following approaches:
- Attach a DropTargetBehavior
- Set the ISDragDrop.AllowDrop attached property to True
- Set the AllowDrop property to True
![]() |
AllowDrop property is only available in SL4 and WPF. |
Making an UIElement Droppable using DropTargetBehavior
The following code demonstrates how to make an UIElement droppable using DropTargetBehavior.
Dropable Grid Element | ![]() |
---|---|
<Grid HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100" Background="Gray" AllowDrop="True"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior AllowDropItem="True" TooltipIcon="accept.png" TooltipText="Drop here."/> </i:Interaction.Behaviors> </Grid> |
Dropable ListBox | ![]() |
---|---|
<ListBox HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior AllowDropItem="True" DropBehavior="Custom" TooltipIcon="accept.png" TooltipText="Drop here."//> </i:Interaction.Behaviors> </ListBox> |
With DropTargetBehavior, you can easily customize the tooltip when an object is being dragged over to a target element by specifying the TooltipIcon property and the TooltipText property. You can also determine the drop action from DropBehavior property if the drop target is a Panel element.
The following list explains several drop behaviors that you can apply:
- AppendChild
Remove the dragged object from original source and append it to drop target's children. - Replace
Remove the dragged object from original source and replace the drop target's children. - Custom
Requires user implementation on Drop event.
To learn how to handle Drop event, see How to: Copy the dragged object when dropped to the drop target and How to: Remove the drag object when dropped to drop target.
![]() |
All drag-drop related events including the DropEvent are built with routed events architecture. This allows you to handle the events anywhere in the visual tree. To learn more about routed event, see Routed Events Overview. |
Making an UIElement Droppable using Intersoft:ISDragDrop.AllowDrop attached property
The following code demonstrates how to make an UIElement droppable by using the ISDragDrop.AllowDrop attached property.
XAML | ![]() |
---|---|
<ListBox HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100" Intersoft:ISDragDrop.AllowDrop="True"> </ListBox> |
This approach is only used to mark the UIElement as a droppable element. It does not include built-in handling such as in DropTargetBehavior thus requires you to write additional logic at the Drop event. To learn how to handle Drop event, see How to: Copy the dragged object when dropped to the drop target and How to: Remove the drag object when dropped to drop target.
![]() |
Since Silverlight 3 does not have AllowDrop property in UIElement, the Intersoft:ISDragDrop.AllowDrop attached property is introduced to maintain code compatibility across Silverlight 3, Silverlight 4 and WPF. |
Making an UIElement Droppable using AllowDrop attached property
The following code demonstrates how to make an UIElement droppable using AllowDrop property.
XAML | ![]() |
---|---|
<ListBox HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100" AllowDrop="True"> </ListBox> |
This approach is only used to mark the UIElement as a droppable element. It doesn't include built-in handling such as in DropTargetBehavior thus requires you to write additional logic at the Drop event. To learn more how to handle Drop event, see How to: Copy the dragged object when dropped to the drop target and How to: Remove the drag object when dropped to drop target.
![]() |
AllowDrop property is only available in Silverlight 4 and WPF |
Customizing Tooltip when Entering DropTarget
You can customize the tooltip text and icon of the drag-drop visual cues when the dragged object is over the drop target. The DropTargetBehavior already has the properties that allow you customize it directly in the form of TooltipIcon and TooltipText as explained in the following code.
Customizing Tooltip | ![]() |
---|---|
<Grid HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100" Background="Gray" AllowDrop="True"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior AllowDropItem="True" TooltipIcon="accept.png" TooltipText="Drop here."/> </i:Interaction.Behaviors> </Grid> |
For the first two approaches, you need to manually change the tooltip text and icon during DragEnter event. To learn more how to handle DragEnter event, see How to: Change tooltip when hovering drop target.
Drag Drop Scope
ClientUI provides a comprehensive drag-drop framework that enables you to easily create fluid drag and drop user experiences. When an object is being dragged, the drag-drop framework detects the available drop target within a certain scope which is determined by the DragDropScope property. The default value for this property is Global which means that the scope is set to the root visual of your application. In this case, the drag-drop framework will search for any droppable controls available in your application.
In certain scenarios, you might want to limit the scope of the drag drop operation. This can be done by changing the DragDropScope property to Parent, then apply the ISDragDrop.IsDragDropScope attached property to the element which the drag-drop operation should be scoped.
To understand about the drag-drop scope capability, consider the following scenario.

XAML | ![]() |
---|---|
<Grid x:Name="LayoutRoot" Background="White"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="200"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid Background="#6600FF00" x:Name="GreenContainer"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior/> </i:Interaction.Behaviors> </Grid> <Grid Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition Height="200"/> <RowDefinition/> </Grid.RowDefinitions> <Grid Background="#66FF0000" x:Name="RedContainer"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior/> </i:Interaction.Behaviors> </Grid> <Grid Grid.Row="1" Background="#66FFD200"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid HorizontalAlignment="Center" Height="150" VerticalAlignment="Center" Width="150" Background="Gray" Margin="20,0" x:Name="SiblingContainer"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior/> </i:Interaction.Behaviors> </Grid> <Grid HorizontalAlignment="Center" Height="150" VerticalAlignment="Center" Width="150" Background="Gray" Margin="20,0" x:Name="SourceContainer"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior/> </i:Interaction.Behaviors> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <i:Interaction.Behaviors> <Intersoft:DragDropBehavior DragEffect="Move" DragDropScope="Global"/> </i:Interaction.Behaviors> <Image Source="folder.png" Height="64" Width="64"/> <TextBlock Text="My Archive" HorizontalAlignment="Center" VerticalAlignment="Center"/> </StackPanel> </Grid> </StackPanel> </Grid> </Grid> </Grid> </Grid> |
In this scenario, the dragable element is set to My Archive object while the droppable targets are set to the GreenContainer, the RedContainer, the SiblingContainer and the SourceContainer.
If the DragDropScope property is set to Global, the objects can be dragged and dropped into any of the drop targets. You can limit the drag-drop scope by setting the DragDropScope property to Parent and determine the drag-drop scope by using the Intersoft:ISDragDrop.ISDragDropScope attached property. See the following example.
XAML | ![]() |
---|---|
<Grid x:Name="LayoutRoot" Background="White"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="200"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid Background="#6600FF00" x:Name="GreenContainer"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior/> </i:Interaction.Behaviors> </Grid> <Grid Grid.Column="1" x:Name="RedContainer"> <Grid.RowDefinitions> <RowDefinition Height="200"/> <RowDefinition/> </Grid.RowDefinitions> <Grid Background="#66FF0000"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior/> </i:Interaction.Behaviors> </Grid> <Grid Grid.Row="1" Background="#66FFD200" Intersoft:ISDragDrop.IsDragScope="True"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid HorizontalAlignment="Center" Height="150" VerticalAlignment="Center" Width="150" Background="Gray" Margin="20,0" x:Name="SiblingContainer"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior/> </i:Interaction.Behaviors> </Grid> <Grid HorizontalAlignment="Center" Height="150" VerticalAlignment="Center" Width="150" Background="Gray" Margin="20,0" x:Name="SourceContainer"> <i:Interaction.Behaviors> <Intersoft:DropTargetBehavior/> </i:Interaction.Behaviors> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <i:Interaction.Behaviors> <Intersoft:DragDropBehavior DragEffect="Move" DragDropScope="Parent"/> </i:Interaction.Behaviors> <Image Source="folder.png" Height="64" Width="64"/> <TextBlock Text="My Archive" HorizontalAlignment="Center" VerticalAlignment="Center"/> </StackPanel> </Grid> </StackPanel> </Grid> </Grid> </Grid> </Grid> |
With this configuration you are able to drag the My Archive object to SiblingContainer but not to RedContainer or GreenContainer.
Drag and Drop Panel
In addition to the behaviors and API, ClientUI's drag-drop framework also provides panels that include built-in drag and drop functionality which makes drag and drop implementation very simple and easy. These panels are built on the top of core drag-drop framework and can be consumed by ItemsControl to enabled drag-drop functionality for its items collection.
Introducing UXPanel
UXPanel is the base class of all panel controls in ClientUI that expose the drag-drop capability. Every item registered under UXPanel will automatically have a DragDropBehavior attached, so you do not need to manually register the DragDropBehavior to the UXPanel, unless you want to override the drag-drop behaviors for certain items.
UXPanel has a set of specific properties that controls the drag and drop behaviors which are explained in the following list.
- AllowDropItem
AllowDropItem indicates whether the panel can accept drop. (Making the panel as droppable target). - AllowMoveItem
AllowMoveItem indicates whether the item can be moved to other droppable target. - AllowReorderItem
AllowReorderItem indicates whether the item can be reordered within the panel. - AllowRemoveItem
AllowRemoveItem indicates whether the item can be removed from panel by dropping it at empty space. - DragMode
DragMode indicates the drag action, whether it is a Copy or a Move action.
Move action will move the object from its original container to the target droppable container, while copy action will require user to create the copy object and insert it to the target droppable container. Note that when you set the DragMode property to Copy action, you can not reorder the item even though AllowReorderItem is set to true.
Each property above unlocks specific actions that you can do. Depending on your requirements, you will need enable or disable several settings.
The following section discusses the combination of settings to achieve common drag-drop scenarios.
-
DragMode = Copy, AllowMoveItem = True
Scenario: Enable drag drop on source panel and perform copy action on drop target. -
-
DragMode = Move, AllowMoveItem = True, AllowReorderItem = True
Scenario: Enable reordering item within the panel and drag-drop on other available drop target. -
DragMode = Move, AllowRemoveItem = True, AllowReorderItem = True
Scenario: Enable reordering item within the panel and item removal when drop into empty space. -
DragMode = Move, AllowMoveItem = True, AllowRemoveItem = True, AllowReorderItem = True
Scenario: Enable reordering item within the panel, item removal when drop into empty space and drag-drop on other available drop target.
Customizing Tooltip
When working with drag-drop, visual hints is important to notify users of the current drag-drop status. UXPanel provides built-in visual hints - such as predefined tooltip - that depends on the settings and the current user action, which significantly simplifies the development process to create fluid drag and drop user experiences.
For example:
- DragMode = Move, AllowRemoveItem = False
Using this configuration, the tooltip will show a "Move" visual hint when you initiated a drag operation on an object. As soon as the object is dragged out from the panel, the tooltip will show a "Not Allowed" visual hint until the object is over a droppable target, or when the source panel receives a command to set the tooltip back to "Move". - DragMode = Move, AllowRemoveItem = True
Using this configuration, the tooltip will show a "Move" visual hint when you initiated a drag operation on an object. As soon as the object is dragged out from the panel, the tooltip will show a"Remove" visual hint.
Generally there are three main entry points where you can effectively customize the visual hints:
-
InitialDrag Event
To change the tooltip in InitialDrag event, you can utilize the properties provided by UXPanel such as DragDropTooltipIcon and DragDropTooltipText. Changing these properties basically overrides all built-in visual hints, which means the visual hints will always be the same regardless of where the object is moved to.
-
DragEnter Event (entering a droppable target)
To change the tooltip when entering a droppable target or during DragEnter event, see How to: Change tooltip when hovering drop target.
-
DragLeave Event (leaving droppable target / source panel)
To change the tooltip when leaving a droppable target or during DragLeave event, see How to: Change tooltip when leaving drop target.
Integration With ItemsControl
ItemsControl such as ListBox (native), UXListBox, UXFlow, and many others use Panel to arrange their items. You can change the Panel used to arrange those items from ItemsPanel property. This gives you the flexibility to choose any panels in order to control the arrangement of your items. You can use UXPanel to easily add drag and drop functionality to your items control.
The following example shows you how to enable drag and drop in a standard ListBox control.
Enable Drag Drop in standard ListBox control | ![]() |
---|---|
<UserControl.Resources> <ItemsPanelTemplate x:Key="ItemsPanelTemplate1"> <Intersoft:UXStackPanel Orientation="Vertical" AllowMoveItem="True" AllowDropItem="True" AllowReorderItem="True" AllowRemoveItem="True"/> </ItemsPanelTemplate> <ItemsPanelTemplate x:Key="ItemsPanelTemplate2"> <Intersoft:UXStackPanel Orientation="Vertical" AllowMoveItem="True" AllowDropItem="True" AllowReorderItem="True"/> </ItemsPanelTemplate> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <StackPanel HorizontalAlignment="Left" VerticalAlignment="Center" Width="250"> <ListBox x:Name="ListBox1" ItemsPanel="{StaticResource ItemsPanelTemplate1}"> <ListBoxItem Content="To-do: Prepare Walkthrough Materials"/> <ListBoxItem Content="To-do: Prepare Video Materials"/> <ListBoxItem Content="To-do: Create Press Release"/> </ListBox> <Intersoft:FieldLabel Header="Selected Index: " HeaderWidth="100" HorizontalHeaderAlignment="Right"> <TextBlock Text="{Binding SelectedIndex, ElementName=ListBox1}" VerticalAlignment="Center"/> </Intersoft:FieldLabel> <Intersoft:FieldLabel Header="Selected Item: " HeaderWidth="100" HorizontalHeaderAlignment="Right"> <TextBlock Text="{Binding SelectedItem.Content, ElementName=ListBox1}" VerticalAlignment="Center"/> </Intersoft:FieldLabel> </StackPanel> <StackPanel HorizontalAlignment="Right" VerticalAlignment="Center" Width="250"> <ListBox x:Name="ListBox2" ItemsPanel="{StaticResource ItemsPanelTemplate2}"> <ListBoxItem Content="To-do: Fix Bug #1337"/> <ListBoxItem Content="To-do: Enhance Drag Drop Logic"/> <ListBoxItem Content="To-do: Create Sample"/> </ListBox> <Intersoft:FieldLabel Header="Selected Index: " HeaderWidth="100" HorizontalHeaderAlignment="Right"> <TextBlock Text="{Binding SelectedIndex, ElementName=ListBox2}" VerticalAlignment="Center"/> </Intersoft:FieldLabel> <Intersoft:FieldLabel Header="Selected Item: " HeaderWidth="100" HorizontalHeaderAlignment="Right"> <TextBlock Text="{Binding SelectedItem.Content, ElementName=ListBox2}" VerticalAlignment="Center"/> </Intersoft:FieldLabel> </StackPanel> </Grid> |
As shown in the above example, you can change the ItemsPanel of each ListBox to a UXPanel (in this case UXStackPanel) which enables you to easily add drag and drop features such as AllowDropItem, AllowMoveItem, and more.
When an item is removed, moved or reordered in an ItemsControl such as ListBox, its item collection will be automatically synchronized. This powerful feature also works in data bound scenarios where a collection of items are bound to the ListBox through ItemsSource.
Working with Unbound ItemsControl and Bound ItemsControl
As illustrated in the above code example, you can change the ItemsPanel of an ItemsControl with UXPanel to enable drag and drop operations in ItemsControl. The ItemsControl can be configured in either unbound or bound mode.
When moving item between ItemsControl it is recommended to use the same mode for both ItemsControl (source and destination) to enable the automatic items synchronization. However, if your scenario requires the item to be moved using different mode, you need to handle the synchronization manually.
To learn how to handle the item drop from different bound mode, see How-to: Move item from bound ListBox to unbound ListBox using UXPanel and How-to: Move item from unbound ListBox to bound ListBox using UXPanel.
Working with Transformable Item
Having the understanding of the concept that drag-drop operations can be easily enabled in any controls that derive from ItemsControl, your application may consist of several different types of dragable ItemsControl where the drag-drop operations should work together across these controls.
ClientUI introduces numerous built-in dragable ItemsControl such as UXListBox, UXAccordion and UXDock. You can easily drag item from one control to another without requiring additional code thanks to the ITransformInfo interface implemented by each item control.
Drag and Drop Events
Drag-and-drop operations support an event driven model. Both the drag source and the drop target use a standard set of events to handle drag-and-drop operations. The following list summarizes the drag-and-drop events sequence.
On Drag Start
-
ISDragDrop.DragSourceEvent (EventType = DragInit)
This is a bubbling event, raised by drag source. -
ISDragDrop.DragInitEvent
This is a bubbling event, raised by drag source. -
ISDragDrop.ShadowInitEvent
This is a bubbling event, raised by drag source. -
ISDragDrop.ShadowCreatedEvent
This is a bubbling event, raised by drag source. -
ISDragDrop.DragSourceEvent (EventType = DragStart)
This is a bubbling event, raised by drag source. -
ISDragDrop.DragStartEvent
This is a bubbling event, raised by drag source. -
ISDragDrop.DragSourceEvent (EventType = DragStarted)
This is a bubbling event, raised by drag source. -
ISDragDrop.DragStartedEvent
This is a bubbling event, raised by drag source. - DragDrop.PreviewGiveFeedBackEvent
This is a bubbling event, raised by drag source. - DragDrop.GiveFeedBackEvent
This is a bubbling event, raised by drag source.
On Dragging
- ISDragDrop.DragSourceEvent (EventType = DragOver)
This is a bubbling event, raised by drag source. - ISDragDrop.DropObjectChangedEvent
This is a bubbling event, raised by drop target. - ISDragDrop.PreviewQueryDropStateEvent (EventType = DragLeave)
This is a tunneling event, raised by drop object. - ISDragDrop.QueryDropStateEvent (EventType = DragLeave)
This is a bubbling event, raised by drop object. - ISDragDrop.PreviewQueryDropStateEvent (EventType = DragEnter)
This is a tunneling event, raised by drop object. - ISDragDrop.QueryDropStateEvent (EventType = DragEnter)
This is a bubbling event, raised by drop object. - ISDragDrop.PreviewQueryDropStateEvent (EventType = DragOver)
This is a tunneling event, raised by drop object. - ISDragDrop.QueryDropStateEvent (EventType = DragOver)
This is a bubbling event, raised by drop object. - ISDragDrop.DragSourceEvent (EventType = DragLeave)
This is a bubbling event, raised by drag source. - DragDrop.PreviewDragLeaveEvent
This is a tunneling event, raised by drop target. - DragDrop.DragLeaveEvent
This is a bubbling event, raised by drop target. - ISDragDrop.DragSourceEvent (EventType = DragEnter)
This is a bubbling event, raised by drag source. - DragDrop.PreviewDragEnterEvent
This is a tunneling event, raised by drop target. - DragDrop.DragEnterEvent
This is a bubbling event, raised by drop target. - DragDrop.PreviewDragOverEvent
This is a tunneling event, raised by drop target. - DragDrop.DragOverEvent
This is a bubbling event, raised by drop target. - DragDrop.PreviewGiveFeedBackEvent
This is a bubbling event, raised by drag source. - DragDrop.GiveFeedBackEvent
This is a bubbling event, raised by drag source.
On Drop
-
ISDragDrop.DragEndEvent
This is a bubbling event, raised by drag source. -
DragDrop.PreviewDropEvent
This is a tunneling event, raised by drop target. -
ISDragDrop.PrepareDropEvent
This is a bubbling event, raised by drop target. -
DragDrop.DropEvent
This is a bubbling event, raised by drop target. -
ISDragDrop.PreviewQueryDropStateEvent (EventType = Drop)
This is a tunneling event, raised by drop object. - ISDragDrop.QueryDropStateEvent (EventType = Drop)
This is a bubbling event, raised by drop object. - ISDragDrop.DragEnded event
This is a bubbling event, raised by drag source. -
ISDragDrop.DragSourceEvent (EventType = DragReturn)ISDragDrop.DragReturn event
This is a bubbling event, raised by drag source.
This is a bubbling event, raised by drag source. -
ISDragDrop.DropObjectChangedEvent
This is a bubbling event, raised by drop target. - DragDrop.PreviewGiveFeedBackEvent
This is a bubbling event, raised by drag source. - DragDrop.GiveFeedBackEvent
This is a bubbling event, raised by drag source. - ISDragDrop.DragSourceEvent (EventType = DragReturned)
This is a bubbling event, raised by drag source. - ISDragDrop.DragReturnedEvent
This is a bubbling event, raised by drop target. - ISDragDrop.DragReturnedEvent
This is a bubbling event, raised by drag source.
On Key Down (During dragging)
-
DragDrop.PreviewQueryContinueDragEvent
This is a tunneling event, raised by drag source. -
DragDrop.QueryContinueDragEvent
This is a bubbling event, raised by drag source.
When you examine the events sequence above, you will see some kind of redundant events such as ISDragDrop.DragSourceEvent (EventType = DragInit) with ISDragDrop.DragInitEvent, and ISDragDrop.DragSourceEvent (EventType = DragEnter) with DragDrop.DragEnterEvent.
The difference between this event is that ISDragDrop.DragSourceEvent is always raised from the drag source while the other relevant event is raised by either the drag source or drop target depending on the condition.
The benefit to have the ISDragDrop.DragSourceEvent is that you can handle the DragInit, DragStart, DragStarted, DragLeave, DragEnter, DragOver, DragEnd, Drop, DragEnded, DragReturn and DragReturned from the drag source directly. This event gives you the flexibility in your application design where you can handle the drag-drop operations from either the drag source or the drop target.
To help you understand the common usages of the provided events, the following list explains several common scenarios that you can achieve by using the provided events:
- As soon the drag about to start, perform a conditional checking to determine whether the item can be drag or not. This can be done during ISDragDrop.DragSourceEvent (EventType = DragInit) or ISDragDrop.DragInitEvent. To learn more about this, see How-to: Perform conditional checking to determine whether an item is dragable.
- Changing the drag shadow object. This can be done during ISDragDrop.ShadowInitEvent. To learn more how to customize the shadow object, see How to: Customize Drag Shadow Object.
- Customize the tooltip when entering a drop target. To learn more, see How to: Change tooltip when hovering drop target.
- Customize the tooltip when leaving a drop target. To learn more, see How to: Change tooltip when leaving drop target.
- Copy the object when dropping it to a drop target. To learn more, see How to: Copy the dragged object when dropped to the drop target.
- Remove the object when dropping it to drop target. To learn more, see How to: Remove the drag object when dropped to drop target.
![]() |
All drag-drop events are built with routed events architecture. This allows you to handle the events anywhere in the visual tree. To learn more about routed event, see Routed Events Overview. |
Working With Data Objects
When dealing with drag and drop, it is common to assign a data to be carried during the drag and drop operation. The drag-drop framework in ClientUI also provides this architecture to store the data in multiple formats.
Storing Data
To store the data, you can use the DragInit event or perform the drag-drop manually by using the provided API, then store the data when you call the API.
To learn how to enable drag and drop using API and storing the data using API, see How-to: Drag an UIElement using API.
To learn how to store the data at DragInit event, see How-to: Store DataObject at DragInit event.
Querying a Data Object for Available Formats
Because a single data object can contain an arbitrary number of data formats, data objects include facilities for retrieving a list of available data formats.
The following example code uses the GetFormats overload to get an array of strings denoting all data formats available in a data object.
GetFormats | ![]() |
---|---|
string sourceData = "Some string data to store..."; byte[] unicodeText = Encoding.Unicode.GetBytes(sourceData); byte[] utf8Text = Encoding.UTF8.GetBytes(sourceData); string uniCodeFormat = "Unicode"; string utf8DataFormat = "UTF-8"; DragDropEventData dataObject = e.Data as DragDropEventData; dataObject.SetData(sourceData); dataObject.SetData(uniCodeFormat, unicodeText); dataObject.SetData(utf8DataFormat, utf8Text); // Get an array of strings, each string denoting a data format // that is available in the data object. This overload of GetDataFormats // returns all available data formats, native and auto-convertible. string[] dataFormats = dataObject.GetFormats(); // Get the number of data formats present in the data object, including both // auto-convertible and native data formats. int numberOfDataFormats = dataFormats.Length; // To enumerate the resulting array of data formats, and take some action when // a particular data format is found, use a code structure similar to the following. foreach (string dataFormat in dataFormats) { if (dataFormat == uniCodeFormat) { // Take some action if/when data in the Text data format is found. break; } else if (dataFormat == utf8DataFormat) { // Take some action if/when data in the string data format is found. break; } } |
Retrieving Data from a Data Object
Retrieving data from a data object in a particular format simply involves calling one of the GetData methods and specifying the desired data format. One of the GetDataPresent methods can be used to check for the presence of a particular data format. GetData returns the data in a Object; depending on the data format, this object can be cast to a type-specific container.
The following example code uses the GetDataPresent(String) overload to first check if a specified data format is available (natively or by auto-convert). If the specified format is available, the example retrieves the data by using the GetData(String) method.
GetData | ![]() |
---|---|
string sourceData = "Some string data to store..."; byte[] unicodeText = Encoding.Unicode.GetBytes(sourceData); byte[] utf8Text = Encoding.UTF8.GetBytes(sourceData); string uniCodeFormat = "Unicode"; string utf8DataFormat = "UTF-8"; DragDropEventData dataObject = e.Data as DragDropEventData; dataObject.SetData(sourceData); dataObject.SetData(uniCodeFormat, unicodeText); dataObject.SetData(utf8DataFormat, utf8Text); string desiredFormat = uniCodeFormat; byte[] data = null; // Use the GetDataPresent method to check for the presence of a desired data format. // This particular overload of GetDataPresent looks for both native and auto-convertible // data formats. if (dataObject.GetDataPresent(desiredFormat)) { // If the desired data format is present, use one of the GetData methods to retrieve the // data from the data object. data = dataObject.GetData(desiredFormat) as byte[]; } |