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); }
结语:
整体核心代码就是拖拽方法那里,感觉写的还是比较通用的。如有疑问,欢迎评论。最后祝大家中秋国庆节日快乐;
从前慢,车马慢。
一生只爱一个人。