草庐IT

c# - TreeView 拖放效果不起作用

coder 2024-06-03 原文

我好像有点问题。我有一个表格,上面有一个 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/

有关c# - TreeView 拖放效果不起作用的更多相关文章

  1. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. ruby-on-rails - "assigns"在 Ruby on Rails 中有什么作用? - 2

    我目前正在尝试学习RubyonRails和测试框架RSpec。assigns在此RSpec测试中做什么?describe"GETindex"doit"assignsallmymodelas@mymodel"domymodel=Factory(:mymodel)get:indexassigns(:mymodels).shouldeq([mymodel])endend 最佳答案 assigns只是检查您在Controller中设置的实例变量的值。这里检查@mymodels。 关于ruby-o

  6. ruby - 字符串文字前面的 * 在 ruby​​ 中有什么作用? - 2

    这段代码似乎创建了一个范围从a到z的数组,但我不明白*的作用。有人可以解释一下吗?[*"a".."z"] 最佳答案 它叫做splatoperator.SplattinganLvalueAmaximumofonelvaluemaybesplattedinwhichcaseitisassignedanArrayconsistingoftheremainingrvaluesthatlackcorrespondinglvalues.Iftherightmostlvalueissplattedthenitconsumesallrvaluesw

  7. ruby - 为什么这个 eval 在 Ruby 中不起作用 - 2

    你能解释一下吗?我想评估来自两个不同来源的值和计算。一个消息来源为我提供了以下信息(以编程方式):'a=2'第二个来源给了我这个表达式来评估:'a+3'这个有效:a=2eval'a+3'这也有效:eval'a=2;a+3'但我真正需要的是这个,但它不起作用:eval'a=2'eval'a+3'我想了解其中的区别,以及如何使最后一个选项起作用。感谢您的帮助。 最佳答案 您可以创建一个Binding,并将相同的绑定(bind)与每个eval相关联调用:1.9.3p194:008>b=binding=>#1.9.3p194:009>eva

  8. ruby-on-rails - Spring 不起作用。 [未初始化常量 Spring::SID::DL] - 2

    我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li

  9. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

  10. ruby - 可以像在 C# 中使用#region 一样在 Ruby 中使用 begin/end 吗? - 2

    我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用

随机推荐