ListView Drag & drop

Posted on 1999-11-29
Medium Priority
Last Modified: 2012-06-21
How to Implement Drag & Drop in a TreeView List View Interface.  Any Examples appreciated.  Specific Problem: Selecting multiple items and draggin them.
Question by:spryken
  • 4
  • 2

Accepted Solution

VBGuru earned 2000 total points
ID: 2241696
You got to extend the idea on this:
Drag & Drop the real selected VB treeview node

Enabling drag and drop in the treeview control can seem deceptively
easy. The property sheet displays two properties for altering this
capability. However, as you probably know, it takes a little code
behind the scenes to actually make the drag and drop work. No
doubt, you've seen the control's OLEStartDrag, OLEDragOver, and
OLEDragDrop events, which you use to implement this technique.
The basic idea behind a drag and drop code procedure is to set a
public node variable equal to the currently selected node,
highlight each node the mouse passes over during the OLEDragOver
event, then add the dragged item to the node under the mouse
pointer to complete the procedure. With this in mind, after first
setting the control's OLEDragMode to 1-ccOLEDragAutomatic, (and
filling it with items, of course) you might think to initiate
the OLEStartDrag event like so:

Option Explicit
Public dragNode As Node, hilitNode As Node

Private Sub TreeView1_OLEStartDrag(Data As MSComctlLib.DataObject, _
     AllowedEffects As Long)
Set dragNode = Treeview1.SelectedNode
End Sub

Here, the code sets the node to be dragged equal to the currently
selected node. Unfortunately, this doesn't work. That's because,
a node only becomes a selected node after the MouseUp event. And
as you know, you initiate a drag by holding the mouse button down.
As is, the above code actually selects the previously selected
node instead. So, to indicate the correct node, use the HitTest
method in the treeview's MouseDown event, like so:

Private Sub TreeView1_MouseDown(Button As Integer, Shift As Integer, _
     x As Single, y As Single)
Set dragNode = TreeView1.HitTest(x, y)
End Sub

This event could replace the OLEStartDrag event entirely, unless of
course you have further node testing that you wish to perform before
starting the drag and drop procedure.

Author Comment

ID: 2241933
My initial problem was getting items from the listview to the Treeview, i seem to have pretty much solved this one by iterating through the  listview collection ie...

For j = 1 To ListView1.ListItems.Count
If ListView1.ListItems(j).Selected = True then (add to the tree)
end if

this is what I was looking for....

However, You did answer the next issue, which is how to drag from the treeview to the listview, and also how to tell which node should the new data be dropped on ... etc...


Expert Comment

ID: 2242679
Option Explicit
'Place Treeview and ListView Control on the form. Let the default name be there.
'Set the Properties of the TreeView Control
'OleDragMode -- Automatic(1)

'Set the Properties of the ListView control
'OleDropMode - Manual

'You Got to decide on the format of  communication. I am using the Text.
'For more details about the oledrag drop check out the vbonline help.

Private Sub Form_Load()
Dim i As Node
Set i = TreeView1.Nodes.Add
i.Text = "First Level"
i.Key = "One"
Set i = TreeView1.Nodes.Add
i.Text = "First Level"
i.Key = "Two"

Set i = TreeView1.Nodes.Add("One", tvwChild, "OneOne", "Second Level")
i.Text = "Second Level"
i.Key = "Three"

End Sub

Private Sub ListView1_OLEDragDrop(Data As ComctlLib.DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
If Data.GetFormat(vbCFText) Then _
MsgBox Data.GetData(vbCFText)
End Sub

Private Sub TreeView1_OLESetData(Data As ComctlLib.DataObject, DataFormat As Integer)
'This event will be triggered as soon as the drag operation starts
'Get the information to be passed to the List View control and Frame the text
Data.SetData "Text to be sent to the List View", vbCFText
End Sub
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.


Expert Comment

ID: 2242684
One of the most powerful and useful features you can add to your Visual Basic applications is the ability to drag text or graphics from one control to another, or from a control to another Windows application, and vice versa. OLE drag-and-drop allows you to add this functionality to your applications.
With OLE drag and drop, you’re not dragging one control to another control to invoke some code (as with the drag and drop discussed earlier in this chapter); you’re moving data from one control or application to another control or application. For example, the user selects and drags a range of cells in Excel, then drops the range of cells into the Data-Bound Grid control in your application.
Almost all Visual Basic controls support OLE drag-and-drop to some degree. The following standard and ActiveX controls (those provided in the Professional and Enterprise editions of Visual Basic) provide automatic support for OLE drag-and-drop, which means that no code needs to be written to either drag from or drop to the control:
Apex Data-Bound Grid      Picture box      Rich text box
Image      Text box      Masked edit box
To enable automatic OLE dragging and dropping for these controls, you set the OLEDragMode and OLEDropMode properties to Automatic.
Some controls only provide automatic support for the OLE drag operation. To enable automatic dragging from these controls, set the OLEDragMode property to Automatic.
Combo box      Data-Bound list box      File list box
Data-Bound Combo box      Directory list box      List box
Tree View      List View      
The following controls only support the OLE drag-and-drop events, meaning that you can program them with code to act either as the source or target of the OLE drag-and-drop operations.
Check box      Frame      Option button
Command button      Label      Drive list box
Note   To determine if other ActiveX controls support OLE drag and drop, load the control into Visual Basic and check for the existence of the OLEDragMode and OLEDropMode properties, or for the OLEDrag method. (A control that does not have automatic support for OLE drag will not have the OLEDragMode property, but it will have an OLEDrag method if it supports OLE drag through code.)
Note   Forms, MDI forms, Document Objects, User Controls, and Property Pages contain the OLEDropMode property and provide support for manual dragging and dropping only.
Using the following OLE drag-and-drop properties, events, and method, you can specify how a given control responds to dragging and dropping.
Category      Item      Description

Properties      OLEDragMode      Enables automatic or manual dragging of a control (if the control supports manual but not automatic OLE drag, it will not have this property but it will support the OLEDrag method and the OLE drag-and-drop events).
      OLEDropMode      Specifies how the control will respond to a drop.
Events      OLEDragDrop      Recognizes when a source object is dropped onto a control.
      OLEDragOver      Recognizes when a source object is dragged over a control.
      OLEGiveFeedback      Provides customized drag icon feedback to the user, based on the source object.
      OLEStartDrag      Specifies which data formats and drop effects (copy, move, or refuse data) the source supports when dragging is initiated.
      OLESetData      Provides data when the source object is dropped.
      OLECompleteDrag      Informs the source of the action that was performed when the object was dropped into the target.
Method      OLEDrag      Starts manual dragging.

Automatic vs. Manual Dragging and Dropping
It is helpful to think of OLE drag-and-drop implementation as either automatic or manual.
Automatic dragging and dropping means that, for example, you can drag text from one text box control to another by simply setting the OLEDragMode and OLEDropMode properties of these controls to Automatic: You don’t need to write any code to respond to any of the OLE drag-and-drop events. When you drag a range of cells from Excel into a Word document, you’ve performed an automatic drag-and-drop operation. Depending upon how a given control or application supports OLE drag and drop and what type of data is being dragged, automatically dragging and dropping data may be the best and simplest method.
Manual dragging and dropping means that you have chosen (or have been forced to) manually handle one or more of the OLE drag-and-drop events. Manual implementation of OLE drag and drop may be the better method when you want to gain greater control over each step in the process, to provide the user with customized visual feedback, to create your own data format. Manual implementation is the only option when a control does not support automatic dragging and dropping.
It is also helpful to define the overall model of the OLE drag-and-drop operation. In a drag and drop operation, the object from which data is dragged is referred to as the source. The object into which the data is dropped is referred to as the target. Visual Basic provides the properties, events, and method to control and respond to actions affecting both the source and the target. It is also helpful to recognize that the source and the target may be in different applications, in the same application, or even in the same control. Depending upon the scenario, you may need to write code for either the source or target, or both.

When an OLE drag-and-drop operation is performed, certain events are generated on the source and target sides. The events associated with the source object are always generated, whether the drag-and-drop operation is automatic or manual. The target-side events, however, are only generated in a manual drop operation. The following illustration shows which events occur and can be responded to on the drag source, and which occur and can be responded to on the drop target.
Figure 11.6   Source-side and target-side events

Which events you’ll need to respond to depends upon how you’ve chosen to implement the drag-and-drop functionality. For example, you may have created an application with a text box that you want to allow to automatically accept dragged data from another application. In this case, you simply set the control’s OLEDropMode property to Automatic. If you want to allow data to be automatically dragged from the text box control as well, you set its OLEDragMode property to Automatic.
If, however, you want to change the default mouse cursors or enhance the functionality for button states and shift keys, you need to manually respond to the source- and target-side events. Likewise, if you want to analyze the data before it is dropped into a control (to verify that the data is compatible, for instance), or delay when the data is loaded into the DataObject object (so that multiple formats don't need to be loaded at the beginning), you'll need to use manual OLE drag-and-drop operations.
Because you can drag and drop data into numerous Visual Basic controls and Windows applications — with varying limitations and requirements — implementing OLE drag and drop can range from straightforward to fairly complex. The simplest implementation, of course, would be dragging and dropping between two automatic objects, whether the object is a Word document, an Excel spreadsheet, or a control in your application that has been set to Automatic. Specifying multiple data formats that would be acceptable to your drop target would be more complicated.
Starting the Drag
What happens in a basic manual OLE drag-and-drop operation within your Visual Basic application? When the user drags data from an OLE drag source (a text box control, for example) by selecting and then holding down the left mouse button, the OLEStartDrag event is triggered and you can then either store the data or simply specify the formats that the source supports. You also need to specify whether copying or moving the data, or both, is allowed by the source.
For More Information   See “Starting the OLE Drag Operation” for more information on the OLEDrag method, the OLEstartDrag event, using the SetData method to specify the supported data formats, and placing data into the DataObject.
Dragging Over the Target
As the user drags over the target, the target’s OLEDragOver event is triggered, indicating that the source is within its boundaries. You then specify what the target would do if the data were dropped there — either copy, move, or refuse the data. By convention, the default is usually move, but it may be copy.
When the target specifies which drop effect will be performed if the source is dropped there, the OLEGiveFeedback event is triggered. The OLEGiveFeedback event is used to provide visual feedback to the user on what action will be taken when the selection is dropped — i.e., the mouse pointer will be changed to indicate a copy, move, or "no drop" action.
As the source is moved around within the boundaries of the target — or if the user presses the SHIFT, CTRL, or ALT keys while holding down the mouse button — the drop effect may be changed. For example, instead of allowing a copy or a move, the data may be refused.
If the user passes beyond the target or presses the ESC key, for example, then the drag operation may be canceled or modified (the mouse pointer may be changed to indicate that the object it is currently passing over will not accept the data).
For More Information   See.“Dragging the OLE Drag Source over the OLE Drop Target” for more information on the OLEDragOver and OLEGiveFeedback events.
Completing the Drag
When the user drops the source onto the target, the target’s OLEDragDrop event is triggered. The target queries the source for the format of the data it contains (or supports, if the data wasn’t placed into the source when the drag was started) and then either retrieves or rejects the data.
If the data was stored when the drag started, the target retrieves the data by using the GetData method. If the data wasn’t stored when the drag started, the data is retrieved by triggering the source’s OLESetData event and then using the SetData method.
When the data is accepted or rejected, the OLECompleteDrag event is triggered and the source can then take the appropriate action: if the data is accepted and a move is specified, the source deletes the data, for example.
For More Information   See “Dropping the OLE Drag Source onto the OLE Drop Target” for more information on the OLEDragDrop event, the OLECompleteDrag event, and using the GetFormat and GetData methods to retrieve data from the DataObject object.

If you want to be able to specify which data formats or drop effects (copy, move, or no drop) are supported, or if the control you want to drag from doesn't support automatic dragging, you need to make your OLE drag operation manual.
The first phase of a manual drag-and-drop operation is calling the OLEDrag method, setting the allowed drop effects, specifying the supported data formats, and, optionally, placing data into the DataObject object.
You use the OLEDrag method to manually start the drag operation and the OLEStartDrag event to specify the allowed drop-action effects and the supported data formats.
The OLEDrag Method
Generally, the OLEDrag method is called from an object’s MouseMove event when data has been selected, the left mouse button is pressed and held, and the mouse is moved.
The OLEDrag method does not provide any arguments. Its primary purpose is to initiate a manual drag and then allow the OLEStartDrag event to set the conditions of the drag operation (for example, specifying what will happen when the data is dragged into another control).
If the source control supports the OLEDragMode property, to have manual control over the drag operation you must set the property to Manual and then use the OLEDrag method on the control. If the control supports manual but not automatic OLE drag, it will not have the OLEDragMode property, but it will support the OLEDrag method and the OLE drag-and-drop events.
Note   The OLEDrag method will also work if the source control’s OLEDragMode property is set to Automatic.
Specifying Drop Effects and Data Formats
In a manual OLE drag operation, when the user begins dragging the source and the OLEDrag method is called, the control's OLEStartDrag event fires. Use this event to specify what drop effects and data formats the source supports.
The OLEStartDrag event uses two arguments to specify supported data formats and whether the data can be copied or moved when the data is dropped (drop effects).
Note   If no drop effects or data formats are specified in the OLEStartDrag event, the manual drag will not be started.
The AllowedEffects Argument
The allowedeffects argument specifies which drop effects the drag source supports. For example:
Private Sub txtSource_OLEStartDrag(Data As _
            VB.DataObject, AllowedEffects As Long)
      AllowedEffects = vbDropEffectMove Or _
End Sub
The target can then query the drag source for this information and respond accordingly.
The allowedeffects argument uses the following values to specify drop effects:
Constant      Value      Description

vbDropEffectNone      0      Drop target cannot accept the data.
vbDropEffectCopy      1      Drop results in a copy. The original data is untouched by the drag source.
VbDropEffectMove      2      Drag source removes the data.

The Format Argument
You specify which data formats the object supports by setting the format argument of the OLEStartDrag event. To do this, you use the SetData method. For example, in a scenario using a rich text box control as a source and a text box control as a target, you might specify the following supported formats:
Private Sub rtbSource_OLEStartDrag(Data As _
            VB.DataObject, AllowedEffects As Long)
      AllowedEffects = vbDropEffectMove Or _

      Data.SetData , vbCFText
      Data.SetData , vbCFRTF
End Sub
The target can query the source to determine which data formats are supported and then respond accordingly — e.g., if the format of the dropped data is not supported by the target, reject the dropped data. In this case, the only data formats that are supported by the source are the text and rich-text formats.
For More Information   See “The OLE Drag and Drop DataObject Object" for more information on format values for the SetData method.
Placing Data into the DataObject object
In many cases, especially if the source supports more than one format, or if it is time-consuming to create the data, you may want to place data into the DataObject object only when it is requested by the target. You can, however, place the data into the DataObject object when you begin a drag operation by using the SetData method in the OLEStartDrag event. For example:
Private Sub txtSource_OLEStartDrag(Data As _
            VB.DataObject, AllowedEffects As Long)
      Data.SetData txtSource.SelText, vbCFText
End Sub
This example clears the default data formats from the DataObject object using the Clear method, specifies the data format (text) of the selected data, and then places the data into the DataObject object with the SetData method.

Author Comment

ID: 2243415
Thanks for your time and trouble, I think you covered it all.  What is the source of this text?

Expert Comment

ID: 2243463
vbonline help

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses

589 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question