我似乎有一个问题.我有一个表格,有树视图.在这个树视图中,有“文件夹”和“项目”.我允许用户为文件夹和项目移动节点/更改层次结构.
我试图在拖放操作生效时更改鼠标光标,但是根本看起来似乎不起作用.我已经改变了所有必要的值,并且在不同的事件期间鼠标光标,但是没有用.
下面的代码有没有什么东西会阻止正确的行为?基本上,显示的光标总是默认的拖放光标(移动,复制等)…请注意,我还启用了TreeView中的HotTracking来启用GiveFeedback,并触发/击中断点.
[编辑] – 感谢汉斯解决方案.基本上,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()方法中的一个微妙错误,它使用该表单的DoDragDrop()方法.在您的情况下,GiveFeedback事件在拖动源上触发,而不是放置目标.换句话说,您的GiveFeedback事件永远不会触发.调试器btw很容易看到,只需在事件处理程序中设置一个断点即可看到它不会运行.固定:
private void tv_Terms_ItemDrag(object sender,ItemDragEventArgs e) { tv_Terms.DoDragDrop(e.Item,DragDropEffects.Move); }
此方法最好也是您要创建光标的方法.而且您应该在DragEnter事件处理程序中加以区分,因此它不允许删除所有内容,请使用e.Data.GetDataPresent(typeof(TreeNode))进行验证.并删除DragOver中的光标操作.