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);


        }

 

结语:

整体核心代码就是拖拽方法那里,感觉写的还是比较通用的。如有疑问,欢迎评论。最后祝大家中秋国庆节日快乐;

posted @ 2023-09-28 14:16  黄金程序员  阅读(252)  评论(0编辑  收藏  举报