c# 拖拽列表顺序 | 拖拽合并分组 | 移除分组功能
动图演示:

背景:
一开始做功能的时候没有增加排序的索引(sort-index),后来要求做拖拽排序功能;所以写了这个不需要初始排序就可以完成的拖拽功能;如果是table表格排序逻辑和这个相似,这里拿这个angular框架的树形菜单来做例子;
核心逻辑:
1,查询列表需要通过多字段进行排序如:SortIndex(新创建的字段,默认值为0),创建时间,Id
2,编写拖拽逻辑,同级别的互相移动。移动后修改全部SortIndex(索引字段);
3,不同级别的相互合并或拆分(修改父Id即可)。移动后修改全部SortIndex(索引字段);
代码展示:
前端方法:
<nz-tree #studentgroupTree [nzData]="treeData" nzShowIcon [nzSearchValue]="searchTreeNodeValue" (nzSearchValueChange)="searchTreeNode($event)"
nzDraggable nzBlockNode [nzBeforeDrop]="beforeDrop" (nzOnDrop)="onDropTreeNode($event)" (nzClick)="clickTreeNode()" >
</nz-tree>
treeData就是调用后台查询的方法返回的数据集合;
其中 [nzBeforeDrop]表示拖拽前的验证;[onDropTreeNode]表示拖拽的方法,在ts或js中调用后台方法;

后端查询方法:
public object GetTreeData()
{
List<Organization> allPermissionOrgList = new List<Organization>() { }; allPermissionOrgList = allPermissionOrgList.OrderBy(t => t.SequenceNo).ThenBy(t => t.CreatedTime).ThenBy(t => t.Id).ToList(); return allPermissionOrgList;
}
排序顺序尽量按照先索引然后创建时间其次ID的排序;
后端拖拽方法:
/// <summary>
/// 移动学员分组
/// </summary>
/// <param name="dragNodeid">拖拽对象</param>
/// <param name="nodeid">目标对象</param>
/// <param name="pos">见上文描述</param>
/// <returns></returns>
public virtual async Task<OperationResult> MoveStudentTreeNode(int dragNodeid, int nodeid, int pos)
{
var dragNode = OrganizationRepository.Get(dragNodeid);
if (dragNode == null)
{
return new OperationResult(OperationResultType.NoChanged);
}
var node = OrganizationRepository.Get(nodeid);
if (node == null)
{
return new OperationResult(OperationResultType.NoChanged);
} List<Organization> GroupList = new List<Organization>(); var OrganizationsList = Organizations.Where(x => x.OrganizationType == 1 && x.DeletedTime == null);
if (node.ParentId != null)
{//有父级,表示本身是子级
GroupList = OrganizationsList.Where(x => x.ParentId == node.ParentId).ToList();
}
else if (node.ParentId == null && pos == 0)
{//没有父级,并且pos等于0 代表拖拽到中间位置了
GroupList = OrganizationsList.Where(x => x.ParentId == node.Id).ToList();
}
else
{//没有父级,表示本身是父级
GroupList = OrganizationsList.Where(x => x.ParentId == null).ToList();
}
GroupList = GroupList.Distinct().OrderBy(t => t.ParentId).ThenBy(t => t.SequenceNo).ThenBy(t => t.Id).ToList(); List<Organization> editedNodeList = new List<Organization>();
string belongId = string.Empty;
switch (pos)
{
case 0:
dragNode.ParentId = node.Id;
belongId = node.Path.Split(',', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
if (!string.IsNullOrEmpty(belongId))
await UserRepository.QueryAsNoTracking().Where(x => x.BelongToRootId == dragNode.Id).UpdateFromQueryAsync(x => new User { BelongToRootId = Convert.ToInt32(belongId) });
SetTreePath(dragNode);
GroupList.Insert(0, dragNode);
for (int i = 0; i < GroupList.Count; i++)
{
var item = GroupList[i];
item.SequenceNo = i + 1;
editedNodeList.Add(item);
}
break;
case -1:
case 1:
if (dragNode.ParentId == node.ParentId)
{//如果是同一目录拖拽
GroupList.Remove(dragNode); var itemIndex = GroupList.IndexOf(node);
if (pos == -1)
GroupList.Insert(itemIndex + 0, dragNode);
else
GroupList.Insert(itemIndex + 1, dragNode); for (int i = 0; i < GroupList.Count; i++)
{
var item = GroupList[i];
item.SequenceNo = i + 1;
editedNodeList.Add(item);
}
}
else
{//如果是不同目录拖拽
dragNode.ParentId = node.ParentId;
belongId = node.Path.Split(',', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
if (!string.IsNullOrEmpty(belongId))
await UserRepository.QueryAsNoTracking().Where(x => x.BelongToRootId == dragNode.Id).UpdateFromQueryAsync(x => new User { BelongToRootId = Convert.ToInt32(belongId) });
//UpdateBelongToRootIds(dragNode.Id, Convert.ToInt32(belongId));
SetTreePath(dragNode); var itemIndex = GroupList.IndexOf(node);
if (pos == -1)
GroupList.Insert(itemIndex + 0, dragNode);
else
GroupList.Insert(itemIndex + 1, dragNode); for (int i = 0; i < GroupList.Count; i++)
{
var item = GroupList[i];
item.SequenceNo = i + 1;
editedNodeList.Add(item);
}
}
break;
default:
break;
}
if (editedNodeList.Count > 0)
await OrganizationRepository.UpdateAsync(GroupList.ToArray());
return new OperationResult(OperationResultType.NoChanged); }
结语:
整体核心代码就是拖拽方法那里,感觉写的还是比较通用的。如有疑问,欢迎评论。最后祝大家中秋国庆节日快乐;
c# 拖拽列表顺序 | 拖拽合并分组 | 移除分组功能的更多相关文章
- 【UWP】拖拽列表项的排序功能实现
在一些允许用户自定义栏目顺序的app(如:凤凰新闻.网易云音乐等),我们可以方便地拖拽列表项来完成列表的重新排序,进而完成对栏目顺序的重排.这个功能很人性化,而实现起来其实很简单(甚至都不用写什么后台 ...
- Android高级控件(六)——自定义ListView高仿一个QQ可拖拽列表的实现
Android高级控件(六)--自定义ListView高仿一个QQ可拖拽列表的实现 我们做一些好友列表或者商品列表的时候,居多的需求可能就是需要列表拖拽了,而我们选择了ListView,也是因为使用L ...
- Android学习系列(11)--App列表之拖拽ListView(下)
接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法. 在这个方法中我们主要是处理 ...
- Android学习系列(10)--App列表之拖拽ListView(上)
研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨. 鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. ...
- Android学习系列--App列表之拖拽ListView(下)
接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法. 在这个方法中我们主要是处理 ...
- Android学习系列--App列表之拖拽ListView(上)
研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨. 鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. 一 ...
- Qt之股票组件-自选股--列表可以拖拽、右键常用菜单
目录 一.开头嘴一嘴 二.效果展示 三.自选股列表 1.列表初始化 2.添加Item 3.右键菜单 4.拖拽Item 5.刷新数据 四.相关文章 原文链接:Qt之股票组件-自选股--列表可以拖拽.右键 ...
- 实现拖拽列表-微信小程序
之前在网上搜索拖拽列表的实现时,发现了有好多的方法都是基于像素位置的计算实现的,这种方法要求列表元素的大小以及列表的位置有着非常严格的要求,修改和拓展起来非常的麻烦.于是我自己动手实现了一个基于页面元 ...
- 基于html5拖拽api实现列表的拖拽排序
基于html5拖拽api实现列表的拖拽排序 html代码: <ul ondrop="drop_handler(event);" ondragover="dragov ...
- WPF拖拽文件(拖入拖出),监控拖拽到哪个位置,类似百度网盘拖拽
1.往wpf中拖文件 // xaml <Grid x:Name="grid_11" DragOver="Grid_11_DragOver" Drop=&q ...
随机推荐
- 介绍一个气缸控制的FB程序块
关键词: 气缸,双控.单控.电磁阀.感应器.初始位置(简称"始位").末端位置(简称"端位").屏蔽功能.延时功能.报警功能 正文: 1.为什么要做气缸FB功能 ...
- 《c#高级编程》第2章C#2.0中的更改(一)——泛型
一.实例 当我们需要编写一些通用的代码,但是不确定它们将处理的数据类型时,泛型就非常有用了.下面是一个简单的 C# 泛型示例: using System; public class Example { ...
- mysql错误ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
- vue3 快速入门系列 —— 其他API
其他API 前面我们已经学习了 vue3 的一些基础知识,本篇将继续讲解一些常用的其他api,以及较完整的分析vue2 和 vue3 的改变. 浅层响应式数据 shallowRef shallow 中 ...
- HL7消息结构
HL7消息用于在不同的医疗保健系统之间传输电子数据,每个消息发送相关特定事件(例如患者入院)的信息.HL7消息采用人类可读格式,本节介绍HL7消息的内容以及HL7消息的组织方式. HL7消息由一个或多 ...
- 【阿里云采购季】3月采购完,IT运维躺赢一年2
阿里云2020上云采购季正式上线啦!今年的采购季可以逛些啥? 采购季正式期时间: 3月2日-3月31日 在这段时间里,想买啥就买吧,别忘了把想买的产品加入购物车噢,特惠产品叠加购物车满减,更划算 ...
- EasyNLP开源|中文NLP+大模型落地,EasyNLP is all you need
简介:EasyNLP背后的技术框架如何设计?未来有哪些规划?今天一起来深入了解. 作者 | 临在.岑鸣.熊兮 来源 | 阿里开发者公众号 一 导读 随着BERT.Megatron.GPT-3等预训练 ...
- CNCF 沙箱项目 OCM Placement 多集群调度指南
简介:在这篇文章中,将介绍 Placement 如何选择到所需的集群,Placement 可以提供的调度功能,以及一些场景下的最佳实践,使用者可以参考示例来编写符合自己要求的 Placement.其 ...
- 五福背后的 Web 3D 引擎 Oasis Engine 正式开源
简介: Oasis 从开源走向新的起点,用 3D 化的交互和表达让世界变得更美好. 相信大家已经体验了今年支付宝五福的活动,无论是今年的五福首页还是打年兽游戏都是由蚂蚁互动图形引擎(代号:Oasis ...
- Kubernetes 已经成为云原生时代的安卓,这就够了吗?
简介:本文将介绍如何在 Kubernetes 上构建新的应用管理平台,提供一层抽象以封装底层逻辑,只呈现用户关心的接口,使用户可以只关注自己的业务逻辑,管理应用更快更安全. 作者:司徒放 导语:云原 ...