我好像有点问题。我有一个表格,上面有一个 TreeView 。在此 TreeView 中,有“文件夹”和“项目”。我允许用户移动节点/更改文件夹和项目的层次结构。
我试图在拖放操作生效时更改鼠标光标,但是这似乎根本不起作用。我已经更改了所有必要的值,以及不同事件期间的鼠标光标,但无济于事。
下面的代码中是否缺少某些会阻止正确行为的内容?基本上,显示的光标始终是默认的拖放光标(移动、复制等)...请注意,我还在 TreeView 上启用了 HotTracking 以启用 GiveFeedback 并触发/命中断点。
[编辑] -- 感谢 Hans 提供的解决方案。基本上,DoDragDrop 调用必须通过使用其 FQN 以您想要的控件为目标。源代码管理是否触发 ItemDrag 事件并不重要,您必须明确指定它。请参阅下面更新的代码。
#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
最佳答案
DoDragDrop(e.Item, DragDropEffects.Move);
这是您的 tv_Terms_ItemDrag() 方法中的一个细微错误,它使用了 form 的 DoDragDrop() 方法。这对您的情况很重要,GiveFeedback 事件是在拖动源 上触发的,而不是在放置目标上触发的。换句话说,您的 GiveFeedback 事件永远不会触发。顺便说一句,使用调试器很容易看到,只需在事件处理程序上设置一个断点就可以看到它永远不会运行。修复:
private void tv_Terms_ItemDrag(object sender, ItemDragEventArgs e)
{
tv_Terms.DoDragDrop(e.Item, DragDropEffects.Move);
}
此方法最好也是您要创建游标的方法。并且您应该在 DragEnter 事件处理程序中更加区分,因此它不允许删除一切,使用 e.Data.GetDataPresent(typeof(TreeNode)) 进行验证。并删除 DragOver 中的光标操作。
关于c# - TreeView 拖放效果不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34398174/