Blazor的Telerik UI?下载30天免费试用

拖放

TreeView的拖放功能允许您在同一个TreeView的不同父节点之间或在不同Telerik TreeView实例之间移动一个或多个节点。

本文将分为以下几部分:

基础知识

要启用拖放功能:

  1. 设置可拖动的参数。< TelerikTreeView >真正的

  2. 使用OnDrop事件来处理拖放操作并根据业务逻辑修改数据源。

OnDrop事件

OnDrop事件在用户将节点拖放到新位置时触发。它允许您根据用户删除元素的位置来操作数据集合。

事件参数

OnDrop事件提供类型的对象TreeViewDropEventArgs到它的事件处理程序,该事件处理程序公开以下字段:

参数 类型 描述
对象 表示被拖动的行。您可以将该对象强制转换为您的模型类。
DestinationItem 对象 控件所在的行被删除。您可以将该对象强制转换为您的模型类。
项目 对象 表示被拖动的行。您可以将该对象强制转换为您的模型类。
DropPosition 枚举 控件的位置,其成员允许您确定所删除项相对于控件的位置的确切位置DestinationItem
DestinationGrid 对象 删除行所在网格的引用。这适用于在不同网格之间拖放行。
DestinationIndex 字符串 第二个分量中出现下降的索引。
DestinationComponentId 字符串 Id第二部分会发生下跌。

例子

拖放之间的树视图,网格,树名单和调度器

该功能允许在TreeView之间拖动项目,网格TreeList而且调度器.要实现此目标,请设置可拖动的/RowDraggable参数,并通过事件-实现它OnDrop/OnRowDrop

拖放调度器到网格,TreeList, TreeView是然而,支持。只有相反的方式。

在TreeView和Grid之间拖放
在Grid和TreeView中拖放。*@ @using System.Collections.Generic;@using System.Collections.ObjectModel;@inject PersonService;              @code {public List GridData {get;设置;} public TelerikGrid GridRef {get;设置;} public TelerikTreeView TreeRef {get; set; } public TreeViewObservableFlatDataService TreeService { get; set; } public ObservableCollection TreeData { get; set; } protected override async Task OnInitializedAsync() { await LoadData(); } private async Task LoadData() { var people = await PersonService.GetPeopleAsync(); GridData = people.Take(10).ToList(); TreeService = new TreeViewObservableFlatDataService("Item"); TreeData = TreeService.GetFlatItems(); } private void GridRowDrop(GridRowDropEventArgs args) { foreach (var item in args.Items) { GridData.Remove(item); } if (args.DestinationComponentId == "TreeView1") { var destinationItem = (BaseFlatItem)TreeRef.GetItemFromDropIndex(args.DestinationIndex); args.Items .Select(item => new BaseFlatItem() { Text = item.Name, Id = Guid.NewGuid() }) .ToList() .ForEach(item => UpdateTreeView(item, destinationItem, args.DropPosition)); } else if (args.DestinationComponentId == "Grid1") { InsertItemsIntoGrid(args.Items, args.DestinationItem, args.DropPosition); } } private void TreeViewDrop(TreeViewDropEventArgs args) { var item = args.Item as BaseFlatItem; if (args.DestinationComponentId == "TreeView1") { UpdateTreeView(item, args.DestinationItem as BaseFlatItem, (GridRowDropPosition)(int)args.DropPosition); } else if (args.DestinationComponentId == "Grid1") { var sourceItems = TreeService.GetChildItems(item) .Append(item) .Select(item => new Person() { Name = item.Text, EmployeeId = GridData.Max(x => x.EmployeeId) + 1 }); TreeService.Remove(item, true); var destinationItem = GridRef.GetItemFromDropIndex(args.DestinationIndex); InsertItemsIntoGrid(sourceItems, destinationItem, (GridRowDropPosition)(int)args.DropPosition); GridRef.Rebind(); } } private void InsertItemsIntoGrid(IEnumerable items, Person destinationItem, GridRowDropPosition dropPosition) { var destinationIndex = 0; if (destinationItem != null) { destinationIndex = GridData.IndexOf(destinationItem); if (dropPosition == GridRowDropPosition.After) { destinationIndex += 1; } } GridData.InsertRange(destinationIndex, items); } private void UpdateTreeView(BaseFlatItem item, BaseFlatItem destinationItem, GridRowDropPosition dropPosition) { if (dropPosition == GridRowDropPosition.Over) { TreeService.AddChild(item, destinationItem); } else if (dropPosition == GridRowDropPosition.After) { TreeService.AddNextSibling(item, destinationItem); } else if (dropPosition == GridRowDropPosition.Before) { TreeService.AddPrevSibling(item, destinationItem); } } }
公共类PersonService{私有列表 _people;public List People {get {if (_people == null) {_people = GeneratePeople(30);} return _people;}} public async Task> GetPeopleAsync(){等待Task. delay (50);返回的人;} private List GeneratePeople(int count, int startIndex = 0) {List result = new List();for (int i = startIndex;i < startIndex + count;i++){结果。添加(new Person() {EmployeeId = i, Name = "Employee " + i. tostring (), AgeInYears = i, GraduateGrade = (i % 6) + 1, HireDate = new DateTime(2020,6,1). date。AddDays(count - (i % 7)), MeetingDate = new DateTime(2020,6,1). date。AddDays((i % 4)), IsOutOfOffice = i % 3 == 0 ? true : false }); } return result; } }
使用System.ComponentModel.DataAnnotations;公共类人{[可编辑(错误)]公共int?EmployeeId {get;设置;} [Required(ErrorMessage = "Enter a name")] public string name {get;设置;} [Display(Name = "Age in Years")] [Required(ErrorMessage = "Enter an int Age ")] [Range(0,200, ErrorMessage = "Nobody is that old")] public int?AgeInYears {get;设置;} [Display(Name = "Graduate Grade")] [Required(ErrorMessage = "Enter a Graduate Grade .")] [Range(1,6, ErrorMessage = "Grades vary between 1 and 6.")]公共小数? GraduateGrade { get; set; } [Required(ErrorMessage = "Enter a hire date")] [Range(typeof(DateTime), "10/10/2016", "10/10/2020", ErrorMessage = "Hire Date must be between 10/10/2016 and 10/10/2020")] public DateTime HireDate { get; set; } [Display(AutoGenerateField = false, Name = "Meeting Date")] public DateTime MeetingDate { get; set; } public bool IsOutOfOffice { get; set; } public Person() { GraduateGrade = 1; } }
使用System.Collections.ObjectModel;使用Telerik.DataSource.Extensions;公共类TreeViewObservableFlatDataService{私有字符串ItemText{获取;设置;} private observablecollollection  _observableFlatItems;public TreeViewObservableFlatDataService() {ItemText = "Item";} public TreeViewObservableFlatDataService(string text) {ItemText = text;} private ObservableCollection ObservableFlatItems {get {if (_observableFlatItems == null) {_observableFlatItems = GenerateFlatItems(null, 0, ItemText);} return _observableFlatItems;}} public ObservableCollection GetFlatItems() {return ObservableFlatItems; } private ObservableCollection GenerateFlatItems(Guid? parentId, int level, string parentName) { var items = new ObservableCollection(); for (var i = 1; i <= 4; i++) { var id = Guid.NewGuid(); var name = $"{parentName}{i}"; var item = new BaseFlatItem() { Id = id, ParentId = parentId, HasChildren = level < 2, Text = name }; items.Add(item); if (level < 2) { foreach (var childItem in GenerateFlatItems(id, level + 1, name + ".")) { items.Add(childItem); } } } return items; } #region Reorder public void AddChild(BaseFlatItem flatItem, BaseFlatItem parentFlatItem) { // remove from the collection to assure last place in the collection Remove(flatItem); flatItem.ParentId = parentFlatItem?.Id; // locate previous parent to toggle haschildren property if (parentFlatItem != null) { parentFlatItem.HasChildren = true; } ObservableFlatItems.Add(flatItem); } public void AddChildren(List children) { ObservableFlatItems.AddRange(children); } public void AddPrevSibling(BaseFlatItem flatItem, BaseFlatItem siblingFlatItem) { // remove node Remove(flatItem); // add the node at the position of the sibling node AddSibling(flatItem, siblingFlatItem, 0); } public void AddNextSibling(BaseFlatItem flatItem, BaseFlatItem siblingFlatItem) { // remove node Remove(flatItem); // add the node at the next position of the sibling node AddSibling(flatItem, siblingFlatItem, 1); } private void AddSibling( BaseFlatItem flatItem, BaseFlatItem siblingFlatItem, int direction) { // get parent of the sibling node var parentItem = ObservableFlatItems.FirstOrDefault(f => f.Id == siblingFlatItem.ParentId); // handle movement from another parent flatItem.ParentId = siblingFlatItem.ParentId; // insert the node at the place of the sibling item ObservableFlatItems.Insert(ObservableFlatItems.IndexOf(siblingFlatItem) + direction, flatItem); } public void Remove(BaseFlatItem flatItem, bool removeChildren = false) { // update the hasChildren state of the parent item of the source flat item that is dragged var parentFlatItem = ObservableFlatItems.FirstOrDefault(f => f.Id == flatItem.ParentId); if (parentFlatItem != null) { var childItemsCount = ObservableFlatItems.Count(child => child.ParentId == parentFlatItem.Id); parentFlatItem.HasChildren = childItemsCount > 1; } if (removeChildren) { var children = GetChildItems(flatItem); foreach (var item in children) { ObservableFlatItems.Remove(flatItem); } } ObservableFlatItems.Remove(flatItem); } public List GetChildItems(BaseFlatItem item) { var allRelatedItems = new List(); GetChildItems(item, allRelatedItems); return allRelatedItems; } private void GetChildItems(BaseFlatItem parentItem, List result) { foreach (var item in ObservableFlatItems.Where(it => it.ParentId == parentItem.Id)) { result.Add(item); GetChildItems(item, result); } } #endregion }
公共类BaseFlatItem{公共Guid Id {get;设置;}公共Guid?ParentId {get;设置;}公共字符串文本{获取;设置;} public bool HasChildren {get;设置;}}

查看更多适用的示例网格拖放文章

平的数据

@inject TreeViewFlatDataService TreeViewFlatDataService      @code {public bool Draggable {get;设置;} = true;public List FlatData {get;设置;} protected override void OnInitialized() {FlatData = TreeViewFlatDataService.GetFlatItems();} private void OnDrop(TreeViewDropEventArgs args) {var item = args。Item为BaseFlatItem;var destinationItem = args。DestinationItemas BaseFlatItem; FlatData = TreeViewFlatDataService.ReorderItems(args.DropPosition, item, destinationItem); } }
使用系统;使用System.Collections.Generic;使用来;使用Telerik.Blazor;使用TelerikBlazorAppSource.Models;公共类TreeViewFlatDataService{私有字符串ItemText{获取;设置;} private List _flatItems;private List FlatItems {get {if (_flatItems == null) {_flatItems = GenerateFlatItems(null, 0, ItemText);} return _flatItems; } } public TreeViewFlatDataService() { ItemText = "Item"; } public TreeViewFlatDataService(string text) { ItemText = text; } public List GetFlatItems() { return FlatItems; } private List GenerateFlatItems(Guid? parentId, int level, string parentName) { var items = new List(); for (var i = 1; i <= 4; i++) { var id = Guid.NewGuid(); var name = $"{parentName}{i}"; var item = new BaseFlatItem() { Id = id, ParentId = parentId, HasChildren = level < 3, Text = name }; items.Add(item); if (level < 3) { items.AddRange(GenerateFlatItems(id, level + 1, name + ".")); } } return items; } public List ReorderItems(TreeViewDropPosition position, BaseFlatItem sourceItem, BaseFlatItem destinationItem) { // remove the source item from the current position Remove(sourceItem); // insert in the right place according to the dropposition ReorderCollection(position, sourceItem, destinationItem); return new List(FlatItems); } private void Remove(BaseFlatItem sourceItem) { // update the hasChildren state of the parent item of the source flat item that is dragged var parentFlatItem = FlatItems.FirstOrDefault(f => f.Id == sourceItem.ParentId); if (parentFlatItem != null) { var childItemsCount = FlatItems.Count(child => child.ParentId == parentFlatItem.Id); parentFlatItem.HasChildren = childItemsCount > 1; } FlatItems.Remove(sourceItem); } private void ReorderCollection(TreeViewDropPosition position, BaseFlatItem sourceItem, BaseFlatItem destinationItem) { if (position == TreeViewDropPosition.Over) { // simply change the parent id and add it in the collection, so that the item will be placed on last position sourceItem.ParentId = destinationItem.Id; FlatItems.Add(sourceItem); } else if (position == TreeViewDropPosition.Before) { // handle movement in other parent sourceItem.ParentId = destinationItem.ParentId; FlatItems.Insert(FlatItems.IndexOf(destinationItem), sourceItem); } else if (position == TreeViewDropPosition.After) { // handle movement in other parent sourceItem.ParentId = destinationItem.ParentId; FlatItems.Insert(FlatItems.IndexOf(destinationItem), sourceItem); } } }
公共类BaseFlatItem{公共Guid Id {get;设置;}公共Guid?ParentId {get;设置;}公共字符串文本{获取;设置;} public bool HasChildren {get;设置;}}

分层数据

@inject treeviewherarchicaldataservice treeviewherarchicaldataservice      @code {public bool Draggable {get;设置;} = true;public List HierarchicalData {get;设置;} protected override void OnInitialized() {HierarchicalData = treeviewherarchicaldataservice . gethierarchicalitems ();} private void OnDrop(TreeViewDropEventArgs args) {var item = args。项目为BaseHierarchicalItem;var destinationItem = args。DestinationItemas BaseHierarchicalItem; HierarchicalData = TreeViewHierarchicalDataService.ReorderHierarchicalItems(args.DropPosition, item, destinationItem); } }
使用System.Collections.Generic;使用Telerik.Blazor;公共类treeviewherarchicaldataservice{私有字符串ItemText{获取;设置;} private List _hierarchicalItems;private List HierarchicalItems {get {if (_hierarchicalItems == null) {_hierarchicalItems = GenerateHierarchicalItems(ItemText);} return _hierarchicalItems;}} public treeviewherarchicaldataservice () {ItemText = "Item";} public treeviewherarchicaldataservice (string text) {ItemText = text;} public List GetHierarchicalItems() {return HierarchicalItems; } private List GenerateHierarchicalItems(string parentName, int level = 0) { var items = new List(); for (var i = 1; i <= 4; i++) { var name = $"{parentName}{i}"; var item = new BaseHierarchicalItem() { HasChildren = level < 2, Text = name }; if (level < 2) { item.Items = GenerateHierarchicalItems(name + ".", level + 1); } items.Add(item); } return items; } public List ReorderHierarchicalItems(TreeViewDropPosition position, BaseHierarchicalItem sourceItem, BaseHierarchicalItem destinationItem) { // remove the item from its current place in the collection RemoveItem(sourceItem); // insert in the right place according to the dropposition ReorderCollection(position, sourceItem, destinationItem); return new List(HierarchicalItems); } private void RemoveItem(BaseHierarchicalItem item) { // locate the parent of the source item var sourceParentItem = HierarchicalItems.FindRecursive(it => it.Items?.Contains(item) ?? false); var sourceCollection = sourceParentItem?.Items ?? HierarchicalItems; sourceCollection.Remove(item); } private void ReorderCollection(TreeViewDropPosition position, BaseHierarchicalItem sourceItem, BaseHierarchicalItem destinationItem) { var destinationParentItem = HierarchicalItems.FindRecursive(item => item.Items?.Contains(destinationItem) ?? false); if (destinationParentItem != null) { destinationParentItem.Items = destinationParentItem.Items ?? new List(); } var itemsCollection = destinationParentItem?.Items ?? HierarchicalItems; var destinationItemIndex = itemsCollection.IndexOf(destinationItem); if (position == TreeViewDropPosition.Over) { destinationItem.Items = destinationItem.Items ?? new List(); destinationItem.Items.Add(sourceItem); } else if (position == TreeViewDropPosition.Before) { itemsCollection.Insert(destinationItemIndex, sourceItem); } else if (position == TreeViewDropPosition.After) { itemsCollection.Insert(destinationItemIndex + 1, sourceItem); } } }
使用系统;使用System.Collections.Generic;使用来;使用System.Threading.Tasks;公共静态类BaseHierarchicalItemExtensions{公共静态BaseHierarchicalItem FindRecursive(this List storageItems, Func条件){for (int i = 0;i < storageItems?.Count;i++) {var storageItem = storageItems[i];var matchedItem = storageItem.FindRecursive(condition);if (matchedItem != null){返回matchedItem;返回默认值; } public static BaseHierarchicalItem FindRecursive(this BaseHierarchicalItem storageItem, Func selector) { if (selector(storageItem) == true) { return storageItem; } for (int i = 0; i < storageItem.Items?.Count; i++) { var item = storageItem.Items[i]; if (selector(item)) { return item; } else { var childItem = item.Items.FindRecursive(selector); if (childItem != null) { return childItem; } } } return default; } }
公共类BaseHierarchicalItem{公共int Id{获取;设置;}公共字符串文本{获取;设置;} public List Items {get;设置;} public bool HasChildren {get;设置;} public bool HasItems => Items?计数> 0;}

在不同的树视图之间

当您将项从TreeView的一个实例拖放到另一个实例时,将OnDrop事件为项目最初所在的TreeView触发。

@using System.Collections.ObjectModel < TelerikTreeView @ref拖=“@FirstTree”数据=“@FirstFlatData”= " true " OnDrop =“@OnDropFirst”> < TreeViewBindings > < TreeViewBinding TextField =“文本”ParentIdField = " ParentId " / > < / TreeViewBindings > < / TelerikTreeView > < TelerikTreeView @ref =“@SecondTree”数据=“@SecondFlatData OnDrop =拖“@OnDropSecond”= " true " > < TreeViewBindings > < TreeViewBinding TextField =“文本”ParentIdField = " ParentId " / > < / TreeViewBindings > < / TelerikTreeView > @code{公开TelerikTreeView FirstTree {get;设置;} public TelerikTreeView SecondTree {get;设置;} public TreeViewObservableFlatDataService FirstTreeService {get;设置;} public TreeViewObservableFlatDataService SecondTreeService {get;设置;} public ObservableCollection FirstFlatData {get; set; } public ObservableCollection SecondFlatData { get; set; } protected override Task OnInitializedAsync() { FirstTreeService = new TreeViewObservableFlatDataService("Item"); SecondTreeService = new TreeViewObservableFlatDataService("Node"); FirstFlatData = FirstTreeService.GetFlatItems(); SecondFlatData = SecondTreeService.GetFlatItems(); return base.OnInitializedAsync(); } private void OnDropFirst(TreeViewDropEventArgs args) { var item = args.Item as BaseFlatItem; var destinationItem = args.DestinationItem as BaseFlatItem; if (args.DestinationTreeView != FirstTree) { FirstTreeService.Remove(item); UpdateSecondTree(item, destinationItem, args.DropPosition); } else { UpdateFirstTree(item, destinationItem, args.DropPosition); } } private void OnDropSecond(TreeViewDropEventArgs args) { var item = args.Item as BaseFlatItem; var destinationItem = args.DestinationItem as BaseFlatItem; if (args.DestinationTreeView != SecondTree) { SecondTreeService.Remove(item); UpdateFirstTree(item, destinationItem, args.DropPosition); } else { UpdateSecondTree(item, destinationItem, args.DropPosition); } } private void UpdateFirstTree(BaseFlatItem item, BaseFlatItem destinationItem, TreeViewDropPosition dropPosition) { if (dropPosition == TreeViewDropPosition.Over) { SecondTreeService.AddChild(item, destinationItem); } else if (dropPosition == TreeViewDropPosition.After) { FirstTreeService.AddNextSibling(item, destinationItem); } else if (dropPosition == TreeViewDropPosition.Before) { FirstTreeService.AddPrevSibling(item, destinationItem); } } private void UpdateSecondTree(BaseFlatItem item, BaseFlatItem destinationItem, TreeViewDropPosition dropPosition) { if (dropPosition == TreeViewDropPosition.Over) { SecondTreeService.AddChild(item, destinationItem); } else if (dropPosition == TreeViewDropPosition.After) { SecondTreeService.AddNextSibling(item, destinationItem); } else if (dropPosition == TreeViewDropPosition.Before) { SecondTreeService.AddPrevSibling(item, destinationItem); } } }
使用系统;使用System.Collections.Generic;使用来;使用System.Threading.Tasks;使用System.Collections.ObjectModel;公共类TreeViewObservableFlatDataService{私有字符串ItemText{获取;设置;} private observablecollollection  _observableFlatItems;public TreeViewObservableFlatDataService() {ItemText = "Item";} public TreeViewObservableFlatDataService(string text) {ItemText = text; } private ObservableCollection ObservableFlatItems { get { if (_observableFlatItems == null) { _observableFlatItems = GenerateFlatItems(null, 0, ItemText); } return _observableFlatItems; } } public ObservableCollection GetFlatItems() { return ObservableFlatItems; } public async Task> GetFlatItemsAsync() { await Task.Delay(50); return GetFlatItems(); } private ObservableCollection GenerateFlatItems(Guid? parentId, int level, string parentName) { var items = new ObservableCollection(); for (var i = 1; i <= 4; i++) { var id = Guid.NewGuid(); var name = $"{parentName}{i}"; var item = new BaseFlatItem() { Id = id, ParentId = parentId, HasChildren = level < 3, Text = name }; items.Add(item); if (level < 3) { foreach (var childItem in GenerateFlatItems(id, level + 1, name + ".")) { items.Add(childItem); } } } return items; } public void AddChild(BaseFlatItem flatItem, BaseFlatItem parentFlatItem) { // remove from the collection to assure last place in the collection Remove(flatItem); flatItem.ParentId = parentFlatItem?.Id; // locate previous parent to toggle haschildren property if (parentFlatItem != null) { parentFlatItem.HasChildren = true; } ObservableFlatItems.Add(flatItem); } public void AddPrevSibling(BaseFlatItem flatItem, BaseFlatItem siblingFlatItem) { // remove node Remove(flatItem); // add the node at the position of the sibling node AddSibling(flatItem, siblingFlatItem, 0); } public void AddNextSibling(BaseFlatItem flatItem, BaseFlatItem siblingFlatItem) { // remove node Remove(flatItem); // add the node at the next position of the sibling node AddSibling(flatItem, siblingFlatItem, 1); } private void AddSibling( BaseFlatItem flatItem, BaseFlatItem siblingFlatItem, int direction) { // get parent of the sibling node var parentItem = ObservableFlatItems.FirstOrDefault(f => f.Id == siblingFlatItem.ParentId); // handle movement from another parent flatItem.ParentId = siblingFlatItem.ParentId; // insert the node at the place of the sibling item ObservableFlatItems.Insert(ObservableFlatItems.IndexOf(siblingFlatItem) + direction, flatItem); } public void Remove(BaseFlatItem flatItem) { // update the hasChildren state of the parent item of the source flat item that is dragged var parentFlatItem = ObservableFlatItems.FirstOrDefault(f => f.Id == flatItem.ParentId); if (parentFlatItem != null) { var childItemsCount = ObservableFlatItems.Count(child => child.ParentId == parentFlatItem.Id); parentFlatItem.HasChildren = childItemsCount > 1; } ObservableFlatItems.Remove(flatItem); } }
公共类BaseFlatItem{公共Guid Id {get;设置;}公共Guid?ParentId {get;设置;}公共字符串文本{获取;设置;} public bool HasChildren {get;设置;}}

另请参阅

在本文中
Baidu
map