ListView 多行拖拽排序
核心代码:修改ListView的属性,及绑定事件
// 初始化listView1.
private void InitializeListView()
{
listView1.AllowDrop = true;
listView1.ListViewItemSorter = new ListViewIndexComparer();
//初始化插入标记
listView1.InsertionMark.Color = Color.Red;
//
listView1.ItemDrag += listView1_ItemDrag;
listView1.DragEnter += listView1_DragEnter;
listView1.DragOver += listView1_DragOver;
listView1.DragLeave += listView1_DragLeave;
listView1.DragDrop += listView1_DragDrop;
} // 当一个项目拖拽是启动拖拽操作
void listView1_ItemDrag(object sender, ItemDragEventArgs e)
{
Dictionary<ListViewItem, int> itemsCopy = new Dictionary<ListViewItem, int>();
foreach (ListViewItem item in listView1.SelectedItems)
itemsCopy.Add(item, item.Index);
listView1.DoDragDrop(itemsCopy, DragDropEffects.Move);
} void listView1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.AllowedEffect;
} //像拖拽项目一样移动插入标记
void listView1_DragOver(object sender, DragEventArgs e)
{
// 获得鼠标坐标
Point point = listView1.PointToClient(new Point(e.X, e.Y));
// 返回离鼠标最近的项目的索引
int index = listView1.InsertionMark.NearestIndex(point);
// 确定光标不在拖拽项目上
if (index > -)
{
Rectangle itemBounds = listView1.GetItemRect(index);
if (point.X > itemBounds.Left + (itemBounds.Width / ))
{
listView1.InsertionMark.AppearsAfterItem = true;
}
else
{
listView1.InsertionMark.AppearsAfterItem = false;
}
}
listView1.InsertionMark.Index = index;
} // 当鼠标离开控件时移除插入标记
void listView1_DragLeave(object sender, EventArgs e)
{
listView1.InsertionMark.Index = -;
} // 将项目移到插入标记所在的位置
void listView1_DragDrop(object sender, DragEventArgs e)
{
// 返回插入标记的索引值
int index = listView1.InsertionMark.Index;
// 如果插入标记不可见,则退出.
if (index == -)
{
return;
}
// 如果插入标记在项目的右面,使目标索引值加一
if (listView1.InsertionMark.AppearsAfterItem)
{
index++;
} // 返回拖拽项
Dictionary<ListViewItem, int> items = (Dictionary<ListViewItem, int>)e.Data.GetData(typeof(Dictionary<ListViewItem, int>));
foreach (var item in items)
{
//在目标索引位置插入一个拖拽项目的副本
listView1.Items.Insert(index, (ListViewItem)item.Key.Clone());
// 移除拖拽项目的原文件
listView1.Items.Remove(item.Key);
if (item.Value >= index) index++;
}
} // 对ListView里的各项根据索引进行排序
class ListViewIndexComparer : System.Collections.IComparer
{
public int Compare(object x, object y)
{
return ((ListViewItem)x).Index - ((ListViewItem)y).Index;
}
}
处理技巧:上述的代码大部分是直接从网上下载的,根据个人的需要做了微调。下载的代码实现单行的拖拽,修改的重点是多行的拖拽。实现这个有两个关键的地方:
listView1_ItemDrag的DoDragDrop里面的传参和listView1_DragDrop事件里面对传递过来的数据的解析。
解决的过程分几步:
1. 传递当前选中的所有行。这里可以通过listView1.SelectedItems获取得到。
2. 传递的所有行执行插入和删除。由于引用的问题,没有直接对listView1.SelectedItems进行foreach操作(Remove对这个对象同样有效。会产生变foreach边修改的情况)。复制到新的集合。
3. 插入的顺序问题。譬如,如果是2、3、6、7插入到4后面,根据顺序执行后,会产生2376的后果,这是因为6在4之后,插入了6后,6以前的长度会增加1。解决方法,碰到6>4的情况,6插入完成之后,4++。
ListView 多行拖拽排序的更多相关文章
- ListView列表拖拽排序
ListView列表拖拽排序能够參考Android源代码下的Music播放列表,他是能够拖拽的,源代码在[packages/apps/Music下的TouchInterceptor.java下]. 首 ...
- RecyclerViewItemTouchHelperDemo【使用ItemTouchHelper进行拖拽排序功能】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 记录使用ItemTouchHelper对Recyclerview进行拖拽排序功能的实现. 效果图 代码分析 ItemTouchHel ...
- JS组件系列——Bootstrap Table 表格行拖拽
前言:之前一直在研究DDD相关知识,好久没更新JS系列文章了.这两天做了一个简单的业务需求,觉得效果还可以,今天在这里分享给大家,欢迎拍砖~~ 一.业务需求及实现效果 项目涉及到订单模块,那天突然接到 ...
- RecyclerView拖拽排序和滑动删除实现
效果图 如何实现 那么是如何实现的呢?主要就要使用到ItemTouchHelper ,ItemTouchHelper 一个帮助开发人员处理拖拽和滑动删除的实现类,它能够让你非常容易实现侧滑删除.拖拽的 ...
- Jquery easyui treegrid实现树形表格的行拖拽
前几天修改了系统的一个功能——实现树形列列表的行拖拽,以达到排序的目的.现在基本上功能实现,现做一个简单的总结. 1.拿到这个直接网上搜,有好多,但是看了后都觉得不是太复杂就是些不是特别想看的例子,自 ...
- html5 Sortable.js 拖拽排序源码分析
最近公司项目经常用到一个拖拽 Sortable.js插件,所以有空的时候看了 Sortable.js 源码,总共1300多行这样,写的挺完美的. 本帖属于原创,转载请出名出处. 官网http:// ...
- GridView实现拖拽排序以及数据交互
在研究项目中的一个效果的时候,查找资料过程中发现有人有这么一种需求,就是GridView在实现拖拽排序的基础上,如果是两个GridView之间实现拖拽效果,并要实现数据交互. 一.效果图: 实现这个效 ...
- dragsort html拖拽排序
一.Jquery List DragSort 对于有些页面,如首页的定制,需要进行动态的拖拽排序.由于自己实现比较困难,我们一般会使用一些js插件来实现.dragsort 就是帮助我们完成这一需求.通 ...
- JS组件系列——Bootstrap Table 表格行拖拽(二:多行拖拽)
前言:前天刚写了篇JS组件系列——Bootstrap Table 表格行拖拽,今天接到新的需要,需要在之前表格行拖拽的基础上能够同时拖拽选中的多行.博主用了半天时间研究了下,效果是出来了,但是感觉不尽 ...
随机推荐
- C++中的#和##运算符
#和##运算符 #:构串操作符 构串操作符#只能修饰带参数的宏的形参,它将实参的字符序列(而不是实参代表的值)转换成字符串常量 #define STRING(x) #x#x#x #define TEX ...
- JAVA中使用HTTP 1.1提高基于AXIS 1.4的web service的性能
HTTP 1.1会在第一次连接的时候进行认证, 而在一定时间内保持连接而不用重新验证. 一般情形下,每个web service请求都会在web service服务端验证, 而验证会消耗很多时间, 因此 ...
- [转]session和cookie的区别和联系,session的生命周期,多个服务部署时session管理
Session和Cookie的区别 对象 信息量大小 保存时间 应用范围 保存位置 Session 小量,简单的数据 用户活动时间+一段延迟时间(一般为20分钟) 单个用户 服务器端 Cookie 小 ...
- Java 8 – Convert Map to LIST
Java 8 – Convert Map to LIST Few Java examples to convert a Map to a List Map<String, String> ...
- 转:ECharts图表组件入门教程之Theme:ECharts图表的皮肤是什么?如何给图表换主题(皮肤)Theme?
一.什么是ECharts图表的皮肤(主题)? 针对这个问题我只能这样回答,ECharts图表的主题(皮肤)就犹如人的衣服一样,是用来衬托和渲染主体,使其变得更加美观好看的目的.你去过ECharts图表 ...
- 哈佛大学 Machine Learning
https://am207.github.io/2017/material.html https://am207.github.io/2017/topics.html https://am207.gi ...
- [Windows Azure] Walkthrough to Configure System Center Management Pack for Windows Azure Fabric Preview for SCOM 2012 SP1 (with a MetricsHub Bonus)
The wait is finally over. This is a huge update to the Azure Management Pack over the one that was r ...
- [Windows Azure] Virtual Machine and Cloud Service Sizes for Windows Azure
Virtual machine size CPU cores Memory OS disk space–cloud services OS disk space–virtual machines Ma ...
- Tornado使用-队列Queue
1.tornado队列的特点 和python标准队列queue相比,tornado的队列Queue支持异步 2.Queue常用方法 Queue.get() 会暂停,直到queue中有元素 Queue. ...
- linux命令(46):批量更改文件后缀,文件名
linux shell 1.要将所有 jpeg的后缀名图片文件修改为 jpg文件. rename .jpeg .jpg *.jpeg