I seem to be having a bit of an issue. I have a form on which there is a treeview. In this treeview, there are "folders" and "items". I am allowing the user to move nodes/change hierarchy for both folders and items.
I am attempting to change the mouse cursor when a drag and drop operation is in effect, however that simply does not seem to be working. I have changed all of the necessary values, and the mouse cursor during the different events, but to no avail.
Is there something missing from the code below that would prevent the proper behaviour? Basically, the cursor displayed is always the default drag and drop cursor (move, copy, etc)... Note that i have also enabled HotTracking on the treeview to enable GiveFeedback and it fires/hits the breakpoint.
[EDIT] -- Thanks to Hans for the solution. Basically, the DoDragDrop call must be targeted at the control you want by using its FQN. It doesn't matter if your source control is the one that fires the ItemDrag event, you must explicitly specify it. See code updated below.
#region Drag and Drop Methods and Event Handlers
/// <summary>
/// Performs the necessary actions when the user drags and drops a node around the treeview.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tv_Terms_DragDrop(object sender, DragEventArgs e)
{
// Retrieve the client coordinates of the drop location.
Point targetPoint = this.tv_Terms.PointToClient(new Point(e.X, e.Y));
// Retrieve the node at the drop location.
TreeNode targetNode = this.tv_Terms.GetNodeAt(targetPoint);
// confirm that the target node isn't null
// (for example if you drag outside the control)
if (targetNode != null)
{
// Retrieve the node that was dragged.
TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
TreeNode draggedParentNode = draggedNode.Parent;
//PERFORM DB OPERATIONS HERE>>
// Expand the node at the location
// to show the dropped node.
targetNode.Expand();
}
}
/// <summary>
/// Adds the necessary effect when dragging.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tv_Terms_ItemDrag(object sender, ItemDragEventArgs e)
{
this.tv_Terms.DoDragDrop(e.Item, DragDropEffects.Move);
}
/// <summary>
/// Adds the necessary effect when dragging.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tv_Terms_DragEnter(object sender, DragEventArgs e)
{
if(e.Data.GetDataPresent(typeof(TreeNode)) == true)
e.Effect = DragDropEffects.Move;
}
/// <summary>
/// Selects the appropriate node when the user is dragging an item.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tv_Terms_DragOver(object sender, DragEventArgs e)
{
//THIS METHOD AUTO-SCROLLS THE TREEVIEW IF YOU REACH THE EDGES...
this.tv_Terms.Scroll();
TreeNode node = this.tv_Terms.GetNodeAt(this.tv_Terms.PointToClient(new Point(e.X, e.Y)));
if (node != null)
{
NodeInfo info = node.Tag as NodeInfo;
if (!info.IsContainer)
node = node.Parent;
this.tv_Terms.SelectedNode = node;
}
}
private void tv_Terms_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
//I DON'T CARE WHAT TYPE OF DRAG IT IS, ALWAYS USE THE CUSTOM CURSOR.
e.UseDefaultCursors = false;
Cursor.Current = lastcursor;
}
//I SET/CACHE THE MOUSE CURSOR HERE
private void tv_Terms_MouseDown(object sender, MouseEventArgs e)
{
TreeNode node = this.tv_Terms.GetNodeAt(e.X, e.Y);
if (node != null)
{
//THIS METHOD CREATES THE CUSTOM CURSOR.
Bitmap curs = Helpers.CreateNodeCursorIcon(this.imageList1.Images[node.ImageIndex], node.Text);
this.lastcursor = new Cursor(curs.GetHicon());
//I CONFIRM THE PROPER CURSOR BY PLACING THE IMAGE IN A P.B.
this.pictureBox1.Image = curs;
Cursor.Current = lastcursor;
}
}
#endregion