我好像有点问题.我有一个表格,上面有树视图.在此树视图中,有"文件夹"和"项目".我允许用户移动文件夹和项目的节点/更改层次结构.
我正在尝试在拖放操作生效时更改鼠标光标,但这似乎不起作用.我在不同的事件中更改了所有必要的值和鼠标光标,但无济于事.
下面的代码中是否有某些内容会阻止正常行为?基本上,显示的光标始终是默认的拖放光标(移动,复制等)...请注意,我还在树视图上启用了HotTracking以启用GiveFeedback并且它会触发/命中断点.
[编辑] - 感谢Hans的解决方案.基本上,DoDragDrop调用必须使用其FQN以您想要的控件为目标.如果源控件是触发ItemDrag事件的源控件并不重要,则必须明确指定它.请参阅下面更新的代码
#region Drag and Drop Methods and Event Handlers ////// Performs the necessary actions when the user drags and drops a node around the treeview. /// /// /// 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(); } } ////// Adds the necessary effect when dragging. /// /// /// private void tv_Terms_ItemDrag(object sender, ItemDragEventArgs e) { this.tv_Terms.DoDragDrop(e.Item, DragDropEffects.Move); } ////// Adds the necessary effect when dragging. /// /// /// private void tv_Terms_DragEnter(object sender, DragEventArgs e) { if(e.Data.GetDataPresent(typeof(TreeNode)) == true) e.Effect = DragDropEffects.Move; } ////// Selects the appropriate node when the user is dragging an item. /// /// /// 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
Hans Passant.. 8
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中的光标操作.
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中的光标操作.