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是,会有拖拽的虚线框,但不影响使用。
http://www.codeproject.com/Articles/15059/C-File-Browser
winform上控件的拖拽小结的更多相关文章
- ToolStrip控件左右拖拽移动效果实现
1.主窗体下部添加一个Panel乘放ToolStrip控件以实现ToolStrip在窗体下部定位.2.当ToolStrip控件中子控件超出屏幕时,拖动控件可以实现滑动效果.拖动到控件边缘距窗体边缘1/ ...
- PyQt5控件支持拖拽方法
让控件支持拖拽动作A.setDragEnable(True) 设置A可以拖动B.setAcceptDrops(True) 设置B可以接受拖动B需要满足两个事件1.dragEnterEvent 将A拖到 ...
- C#开发PACS医学影像处理系统(九):序列控件与拖拽
1.先看结构: 创建WPF用户控件:YourTab 创建WPF用户控件:YourItem 创建选项卡时循环添加item,并设置序列缩略图到控件和异步下载的进度条, 1个病人1个或多个Study检查,1 ...
- WPF 实现控件间拖拽内容
想实现这样一个常用功能:在ListBox的一个Item上点住左键,然后拖拽到另外一个控件(如ListView中),松开左键,数据已经拖拽过来. 步骤如下: 1. 设置ListBox 的AllowDro ...
- 【Android】HorizontalScrollView内子控件横向拖拽
前言 网上ListView上下拖动的例子有,效果也很好,但是项目要横着拖的,只要硬着头皮自己写(主要是没找到合适的),参考文章1修改而来,分享一下. 声明 欢迎转载,但请保留文章原始出处:) 博客园 ...
- 怎样在delphi中实现控件的拖拽
下面这2种方法都能实现对控件和窗体的拖拽 方法1 procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift ...
- 【C#/WPF】UI控件的拖拽/拉伸
需求①:控件拖拽——按住鼠标,可自由拖拽控件. 方法:目前看到的办法有两种. 使用ZoomableCanvas:http://www.cnblogs.com/gnielee/archive/2011/ ...
- HTML5 02. 多媒体控件、拖拽事件、历史记录、web存储、应用程序缓存、地理定位、网络状态
多媒体 video:是行内块(text-align: center; 对行内块适用) <figure></figure>: 多媒体标签 : <figcaption> ...
- winform上控件太多,绘制时会逐个出现,通常说双缓冲能解决但实际不能解决的问题的解决方法。
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle ...
随机推荐
- 构建高性能J2EE应用的五种核心策略
对于J2EE,我们知道当开发应用时,在架构设计阶段的决定将对应用的性能和可扩展性产生深远的影响.现在当开发一个应用项目时,我们越来越多地注意到了性能和可扩展性的问题.应用性能的问题比应用功能的不丰富问 ...
- 视图不能由多个 ListView 共享 (View can't be shared by more than one ListView) 的一个解决方法
1.问题的起因 在WPF中遇到一异常,如题. 因此做一个Demo代码来复现问题,代码如下: <Window x:Class="WpfAppThread.MainWindow" ...
- nginx增加ssl支持 - 编译时参数详情列表
./configure \ --with-http_ssl_module \ make && make install nginx编译参数说明如下: --prefix=&l ...
- python yield的解释
链接地址: http://pyzh.readthedocs.io/en/latest/the-python-yield-keyword-explained.html https://www.jians ...
- php的opcode缓存
前言:由php的运行机制决定,其实php在运行阶段我们也是可以进行缓存的从而提高程序运行效率,这就是我们常说的opcode缓存.1.简述php的运行机制(因为本文是写opcode缓存的所以这里只是简要 ...
- Ingress 原理及实例
什么是Ingress 在Kubernetes中,Service和Pod的IP地址只能在集群内部网络中路由,所有到达“边界路由器”(Edge Router)的网络流量要么被丢弃,要么被转发到别处,从概念 ...
- [Leet Code]Path Sum
很简单一道题,搞错了N次,记录一下. public class Solution { private int currSum = 0; public boolean hasPathSum(TreeNo ...
- mybatis 多数据源
<environments default="development"> <environment id="development"> ...
- webapi中取文件的物理路径(server.mappath)
在Webapi中是用不了server.mappath方法的,上网搜索了一下,发现是用如下代码取得文件绝对路径: string logpath = System.Web.Hosting.HostingE ...
- Atitit atiplat_reader 基于url阅读器的新特性
Atitit atiplat_reader 基于url阅读器的新特性 1.1. feature功能特性1 1.2. note1 1.1. feature功能特性 支持url数据源,实际就是只支持一层连 ...