zoukankan      html  css  js  c++  java
  • winform上控件的拖拽小结

    这里罗列出几个相关的事件和属性,具体的实现介绍已有非常优秀的文章了,文章末尾我将会给出,大家可以去参考。

    属性:

    AllowDrop: 目标控件必须设定为true,才能接受拖拽来的东西。

    事件:

    ItemDrag: 源控件在拖动开始时发生。在这里需调用DoDragDrop方法开始拖拽行为。

    DragEnter:目标控件接受到拖拽行为时发生。在这里可以通过e.Effect设定目标控件能接受的拖拽行为。

    DragOver:目标控件接受到拖拽行为时不间断发生。在DragEnter后触发。这里不可做耗时操作。

    DragLeave:拖拽离开目标控件后触发。

    DragDrop:拖拽开始后,在目标控件上松开鼠标时触发。

    比如把一个ListView(A)的ListViewItem拖拽到TreeView(B)上的需要完成的步骤如下。

    1,设置B的AllowDrop=true;

    2,需要添加的事件和事件执行顺序如下:

    有“放”操作时:ItemDrag(A)→DragEnter(B)→DragOver(B)→DragDrop(B) 

    没有“放”操作时:ItemDrag(A)→DragEnter(B)→DragOver(B)→DragLeave(B) 

    下面给一个简单的实现,并实现高亮显示treeview节点:

            // listview
            private void fileView_ItemDrag(object sender, ItemDragEventArgs e)
            {
                var item = e.Item as ListViewItem;
    
                (sender as ListView).DoDragDrop(item.Tag as string, DragDropEffects.Copy);
            }
    
            // treeview
            private void folderView_DragEnter(object sender, DragEventArgs e)
            {
                if (e.Data.GetDataPresent(DataFormats.Text))
                {
                    e.Effect = DragDropEffects.Copy;
                }
            }
    
            private void folderView_DragOver(object sender, DragEventArgs e)
            {
                var location = this.folderView.PointToClient(new Point(e.X, e.Y));
                var node = this.folderView.GetNodeAt(location);
                if (node == null) return;
                if (node.PrevVisibleNode != null)
                {
                    node.PrevVisibleNode.BackColor = node.TreeView.BackColor;
                    node.PrevVisibleNode.ForeColor = node.TreeView.ForeColor;
                }
                if (node.NextVisibleNode != null)
                {
                    node.NextVisibleNode.BackColor = node.TreeView.BackColor;
                    node.NextVisibleNode.ForeColor = node.TreeView.ForeColor;
                }
                node.BackColor = SelectedBackColor; ;
                node.ForeColor = SelectedForeColor;
            }
    
            private void folderView_DragDrop(object sender, DragEventArgs e)
            {
                var abc = e.Data.GetData(DataFormats.Text);
                var location = this.folderView.PointToClient(new Point(e.X, e.Y));
                var node = this.folderView.GetNodeAt(location.X, location.Y);
                // do something...
                ClearTreeNodesDragColor(this.folderView.Nodes);
            }
            private void ClearTreeNodesDragColor(TreeNodeCollection treeNodes)
            {
                foreach (TreeNode node in treeNodes)
                {
                    if (!node.IsVisible)
                        continue;
                    node.BackColor = node.TreeView.BackColor;
                    node.ForeColor = node.TreeView.ForeColor;
                    ClearTreeNodesDragColor(node.Nodes);
                }
            }
            private void folderView_DragLeave(object sender, EventArgs e)
            {
                ClearTreeNodesDragColor(this.folderView.Nodes);
            }

    上面的代码功能不完全,要实现如拖动时显示图标,以及桌面和应用程序之间的互相拖动可以参看下面的几篇文章,这要求有一定的WindowsAPI编程经验,供大家参考吧。

    2014/12/03:

    看回复中有需求要实现TabControl的拖动,网上查了下,需要重写TabControl的部分事件,但并不是很复杂。

    下面给出一个实现,亲测可以使用。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;
    
    namespace WindowsFormsApplication1
    {
        public class DragableTabControl : TabControl
        {
            public DragableTabControl()
            {
            }
    
            protected override void OnMouseDown(MouseEventArgs e)
            {
                base.OnMouseDown(e);
                TabPage tabPage = GetTabPageByTab(new Point(e.X, e.Y));
                if (tabPage != null)
                {
                    this.DoDragDrop(tabPage, DragDropEffects.All);
                }
            }
    
            private TabPage GetTabPageByTab(Point point)
            {
                for (int i = 0; i < this.TabPages.Count; i++)
                {
                    if (GetTabRect(i).Contains(point))
                    {
                        return this.TabPages[i];
                    }
                }
                return null;
            }
    
            protected override void OnDragOver(DragEventArgs e)
            {
                base.OnDragOver(e);
                TabPage source = (TabPage)e.Data.GetData(typeof(TabPage));
                if (source != null)
                {
                    TabPage target = GetTabPageByTab(PointToClient(new Point(e.X, e.Y)));
                    if (target != null)
                    {
                        e.Effect = DragDropEffects.Move;
                        MoveTabPage(source, target);
                    }
                    else
                    {
                        e.Effect = DragDropEffects.None;
                    }
                }
                else
                {
                    e.Effect = DragDropEffects.None;
                }
            }
    
            private void MoveTabPage(TabPage source, TabPage target)
            {
                if (source == target)
                    return;
    
                int targetIndex = -1;
                List<TabPage> lstPages = new List<TabPage>();
                for (int i = 0; i < this.TabPages.Count; i++)
                {
                    if (this.TabPages[i] == target)
                    {
                        targetIndex = i;
                    }
                    if (this.TabPages[i] != source)
                    {
                        lstPages.Add(this.TabPages[i]);
                    }
                }
                this.TabPages.Clear();
                this.TabPages.AddRange(lstPages.ToArray());
                this.TabPages.Insert(targetIndex, source);
                this.SelectedTab = source;
            }
        }
    }
    

    唯一的不足,可能是点击TabPage是,会有拖拽的虚线框,但不影响使用。

    .NET中的Drag and Drop操作(一) 

    http://www.codeproject.com/Articles/15059/C-File-Browser

  • 相关阅读:
    聊天类功能测试用例
    即时通讯软件针对通讯以及协议方面有哪些测试点?
    面试前期准备工作
    黑盒功能业务测试过程
    Web网站实现facebook登录
    Nginx配置SSL实现HTTPS访问
    jQuery判断当前页面是APP内打开还是浏览器打开
    jQuery实现点击图片简单放大效果
    Linux排查PHP-FPM进程过量常用命令
    PHP防止SQL注入攻击和XSS攻击
  • 原文地址:https://www.cnblogs.com/xiashengwang/p/4024505.html
Copyright © 2011-2022 走看看