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 表格行拖拽,今天接到新的需要,需要在之前表格行拖拽的基础上能够同时拖拽选中的多行.博主用了半天时间研究了下,效果是出来了,但是感觉不尽 ...
随机推荐
- 数据库事务隔离级别+Spring 声明性事务隔离级别
数据库事务隔离级别 数据库提供了四种事务隔离级别, 不同的隔离级别采用不同的锁类开来实现. 在四种隔离级别中, Serializable的级别最高, Read Uncommited级别最低. 大多数数 ...
- es5 温故而知新 创建私有成员、私有变量、特权变量的方法
其实js是不支持私有变量的.哪怕到es6的class语法.虽然有许多变相的方式.但非常冗余而不推崇. 这里介绍的实际上也不是class语法,而是普通的函数,并且利用IIFE(闭包)的方式来实现私有. ...
- SpringBoot+mybatis实现多数据源支持
什么是多数据源支持? 简单的说,就是一个项目里,同时可以访问多个不同的数据库. 实现原理 单个数据源在配置时会绑定一套mybatis配置,多个数据源时,不同的数据源绑定不同的mybatis配置就可以了 ...
- 如何在Linux平台下安装JDK
原文链接:http://android.eoe.cn/topic/android_sdk 1.下载Java的开发包JDK: JDK有好几个类型版本,我们只需要选择Java SE类型的版本就行了. 进入 ...
- rpx
rpx(responsive pixel): 可以根据屏幕宽度进行自适应.规定屏幕宽为750rpx.如在iPhone6上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = ...
- Android 推送集成华为,小米,友盟
公司的 app 一直使用的是极光推送,最近反馈比较多的是推送消息收不到,看来需要找新的推送服务了,在国内目前手机品牌占有率比较多的是华为和小米,且这两家都有自己的推送服务,同时一个合作的友商说他们使用 ...
- [jk]服务器远控卡及kvm切换器
远控卡的需求 经常我们有这么一个需求,那就是某一台器服务器突然宕机,不能启动,而机房却在外地.解决这个问题的方法有两种,一是联系机房人员,二是通过idrac卡远程连接.我们必须根据事情的轻重缓急,来选 ...
- ElasticSearch + xpack 使用
ElasticSearch 是一个高可用开源全文检索和分析组件.提供存储服务,搜索服务,大数据准实时分析等.一般用于提供一些提供复杂搜索的应.我们为什么要选择 ElasticSearch ?因为它是一 ...
- async与await 实例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- STL之string类详解
通过在网站上的资料搜集,得到了很多关于string类用法的文档,通过对这些资料的整理和加入一些自己的代码,就得出了一份比较完整的关于string类函数有哪些和怎样用的文档了!下面先罗列出string类 ...