2020-06-29 15:39:18 +08:00
|
|
|
|
using System;
|
2020-10-09 15:13:32 +08:00
|
|
|
|
using System.Collections;
|
2020-06-29 15:39:18 +08:00
|
|
|
|
using System.Collections.Generic;
|
2020-10-09 15:13:32 +08:00
|
|
|
|
using System.Linq;
|
2020-06-29 15:39:18 +08:00
|
|
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
|
|
|
|
|
|
namespace AntDesign
|
|
|
|
|
{
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public partial class Tree<TItem> : AntDomComponentBase
|
2020-06-29 15:39:18 +08:00
|
|
|
|
{
|
2020-10-09 15:13:32 +08:00
|
|
|
|
#region Tree
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点前添加展开图标
|
|
|
|
|
/// </summary>
|
2020-06-29 15:39:18 +08:00
|
|
|
|
[Parameter]
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public bool ShowExpand { get; set; } = true;
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否展示连接线
|
|
|
|
|
/// </summary>
|
2020-06-29 15:39:18 +08:00
|
|
|
|
[Parameter]
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public bool ShowLine { get; set; }
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否展示 TreeNode title 前的图标
|
|
|
|
|
/// </summary>
|
2020-06-29 15:39:18 +08:00
|
|
|
|
[Parameter]
|
|
|
|
|
public bool ShowIcon { get; set; }
|
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否节点占据一行
|
|
|
|
|
/// </summary>
|
2020-06-29 15:39:18 +08:00
|
|
|
|
[Parameter]
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public bool BlockNode { get; set; }
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置节点可拖拽
|
|
|
|
|
/// </summary>
|
2020-06-29 15:39:18 +08:00
|
|
|
|
[Parameter]
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public bool Draggable { get; set; }
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
private void SetClassMapper()
|
|
|
|
|
{
|
|
|
|
|
ClassMapper.Clear().Add("ant-tree")
|
|
|
|
|
.If("ant-tree-show-line", () => ShowLine)
|
|
|
|
|
.If("ant-tree-icon-hide", () => ShowIcon)
|
|
|
|
|
.If("ant-tree-block-node", () => BlockNode)
|
|
|
|
|
.If("draggable-tree", () => Draggable);
|
|
|
|
|
}
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
#endregion Tree
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
#region Node
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
|
|
|
|
[Parameter]
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public RenderFragment Nodes { get; set; }
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public List<TreeNode<TItem>> ChildNodes { get; set; } = new List<TreeNode<TItem>>();
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="treeNode"></param>
|
|
|
|
|
/// <param name=""></param>
|
2020-12-30 18:38:35 +08:00
|
|
|
|
internal void AddNode(TreeNode<TItem> treeNode)
|
2020-10-09 15:13:32 +08:00
|
|
|
|
{
|
|
|
|
|
ChildNodes.Add(treeNode);
|
|
|
|
|
}
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
#endregion Node
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
#region Selected
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 支持点选多个节点(节点本身)
|
|
|
|
|
/// </summary>
|
2020-06-29 15:39:18 +08:00
|
|
|
|
[Parameter]
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public bool Multiple { get; set; }
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 选中的树节点
|
|
|
|
|
/// </summary>
|
2020-12-30 18:38:35 +08:00
|
|
|
|
internal Dictionary<long, TreeNode<TItem>> SelectedNodesDictionary { get; set; } = new Dictionary<long, TreeNode<TItem>>();
|
2020-06-29 15:39:18 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public List<string> SelectedTitles => SelectedNodesDictionary.Select(x => x.Value.Title).ToList();
|
|
|
|
|
|
2020-12-30 18:38:35 +08:00
|
|
|
|
internal void SelectedNodeAdd(TreeNode<TItem> treeNode)
|
2020-06-29 15:39:18 +08:00
|
|
|
|
{
|
2020-12-30 18:38:35 +08:00
|
|
|
|
if (SelectedNodesDictionary.ContainsKey(treeNode.NodeId) == false)
|
|
|
|
|
SelectedNodesDictionary.Add(treeNode.NodeId, treeNode);
|
|
|
|
|
|
|
|
|
|
UpdateBindData();
|
2020-06-29 15:39:18 +08:00
|
|
|
|
}
|
2020-12-30 18:38:35 +08:00
|
|
|
|
|
|
|
|
|
internal void SelectedNodeRemove(TreeNode<TItem> treeNode)
|
2020-06-29 15:39:18 +08:00
|
|
|
|
{
|
2020-12-30 18:38:35 +08:00
|
|
|
|
if (SelectedNodesDictionary.ContainsKey(treeNode.NodeId) == true)
|
|
|
|
|
SelectedNodesDictionary.Remove(treeNode.NodeId);
|
|
|
|
|
|
|
|
|
|
UpdateBindData();
|
2020-06-29 15:39:18 +08:00
|
|
|
|
}
|
2020-12-30 18:38:35 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public void DeselectAll()
|
2020-06-29 15:39:18 +08:00
|
|
|
|
{
|
2020-10-09 15:13:32 +08:00
|
|
|
|
foreach (var item in SelectedNodesDictionary.Select(x => x.Value).ToList())
|
2020-06-29 15:39:18 +08:00
|
|
|
|
{
|
2020-10-09 15:13:32 +08:00
|
|
|
|
item.SetSelected(false);
|
2020-06-29 15:39:18 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-12-30 18:38:35 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 选择的Key
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
|
|
|
|
public string SelectedKey { get; set; }
|
|
|
|
|
|
|
|
|
|
[Parameter]
|
|
|
|
|
public EventCallback<string> SelectedKeyChanged { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 选择的节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
|
|
|
|
public TreeNode<TItem> SelectedNode { get; set; }
|
|
|
|
|
|
|
|
|
|
[Parameter]
|
|
|
|
|
public EventCallback<TreeNode<TItem>> SelectedNodeChanged { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 选择的数据
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
|
|
|
|
public TItem SelectedData { get; set; }
|
|
|
|
|
|
|
|
|
|
[Parameter]
|
|
|
|
|
public EventCallback<TItem> SelectedDataChanged { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 选择的Key集合
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
|
|
|
|
public string[] SelectedKeys { get; set; }
|
|
|
|
|
|
|
|
|
|
[Parameter]
|
|
|
|
|
public EventCallback<string[]> SelectedKeysChanged { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 选择的节点集合
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
|
|
|
|
public TreeNode<TItem>[] SelectedNodes { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 选择的数据集合
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
|
|
|
|
public TItem[] SelectedDatas { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 更新绑定数据
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void UpdateBindData()
|
|
|
|
|
{
|
|
|
|
|
if (SelectedNodesDictionary.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
SelectedKey = null;
|
|
|
|
|
SelectedNode = null;
|
|
|
|
|
SelectedData = default(TItem);
|
|
|
|
|
SelectedKeys = Array.Empty<string>();
|
|
|
|
|
SelectedNodes = Array.Empty<TreeNode<TItem>>();
|
|
|
|
|
SelectedDatas = Array.Empty<TItem>();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var selectedFirst = SelectedNodesDictionary.FirstOrDefault();
|
|
|
|
|
SelectedKey = selectedFirst.Value?.Key;
|
|
|
|
|
SelectedNode = selectedFirst.Value;
|
|
|
|
|
SelectedData = selectedFirst.Value.DataItem;
|
|
|
|
|
SelectedKeys = SelectedNodesDictionary.Select(x => x.Value.Key).ToArray();
|
|
|
|
|
SelectedNodes = SelectedNodesDictionary.Select(x => x.Value).ToArray();
|
|
|
|
|
SelectedDatas = SelectedNodesDictionary.Select(x => x.Value.DataItem).ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SelectedKeyChanged.HasDelegate) SelectedKeyChanged.InvokeAsync(SelectedKey);
|
|
|
|
|
if (SelectedNodeChanged.HasDelegate) SelectedNodeChanged.InvokeAsync(SelectedNode);
|
|
|
|
|
if (SelectedDataChanged.HasDelegate) SelectedDataChanged.InvokeAsync(SelectedData);
|
|
|
|
|
if (SelectedKeysChanged.HasDelegate) SelectedKeysChanged.InvokeAsync(SelectedKeys);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
#endregion Selected
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
#region Checkable
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点前添加 Checkbox 复选框
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
|
|
|
|
public bool Checkable { get; set; }
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public List<TreeNode<TItem>> CheckedNodes => GetCheckedNodes(ChildNodes);
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public List<string> CheckedKeys => GetCheckedNodes(ChildNodes).Select(x => x.Key).ToList();
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
public List<string> CheckedTitles => GetCheckedNodes(ChildNodes).Select(x => x.Title).ToList();
|
|
|
|
|
|
2020-12-30 18:38:35 +08:00
|
|
|
|
private List<TreeNode<TItem>> GetCheckedNodes(List<TreeNode<TItem>> childs)
|
2020-10-09 15:13:32 +08:00
|
|
|
|
{
|
2020-12-30 18:38:35 +08:00
|
|
|
|
List<TreeNode<TItem>> checkeds = new List<TreeNode<TItem>>();
|
2020-10-09 15:13:32 +08:00
|
|
|
|
foreach (var item in childs)
|
2020-06-29 23:24:21 +08:00
|
|
|
|
{
|
2021-01-07 00:41:26 +08:00
|
|
|
|
if (item.Checked) checkeds.Add(item);
|
2020-10-09 15:13:32 +08:00
|
|
|
|
checkeds.AddRange(GetCheckedNodes(item.ChildNodes));
|
2020-06-29 23:24:21 +08:00
|
|
|
|
}
|
2020-10-09 15:13:32 +08:00
|
|
|
|
return checkeds;
|
2020-06-29 23:24:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
//取消所有选择项目
|
|
|
|
|
public void DecheckedAll()
|
2020-06-29 23:24:21 +08:00
|
|
|
|
{
|
2020-10-09 15:13:32 +08:00
|
|
|
|
foreach (var item in ChildNodes)
|
|
|
|
|
{
|
|
|
|
|
item.SetChecked(false);
|
|
|
|
|
}
|
2020-06-29 23:24:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
#endregion Checkable
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
#region Search
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
public string _searchValue;
|
2021-01-07 00:41:26 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 按需筛选树,双向绑定
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
|
|
|
|
public string SearchValue
|
|
|
|
|
{
|
|
|
|
|
get => _searchValue;
|
|
|
|
|
set
|
2020-06-29 23:24:21 +08:00
|
|
|
|
{
|
2020-10-09 15:13:32 +08:00
|
|
|
|
if (_searchValue == value) return;
|
|
|
|
|
_searchValue = value;
|
|
|
|
|
if (string.IsNullOrEmpty(value)) return;
|
|
|
|
|
foreach (var item in ChildNodes)
|
2020-06-29 23:24:21 +08:00
|
|
|
|
{
|
2020-10-09 15:13:32 +08:00
|
|
|
|
SearchNode(item);
|
2020-06-29 23:24:21 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 返回一个值是否是页节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public Func<TreeNode<TItem>, bool> SearchExpression { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查询节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="treeNode"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-12-30 18:38:35 +08:00
|
|
|
|
private bool SearchNode(TreeNode<TItem> treeNode)
|
2020-06-29 23:24:21 +08:00
|
|
|
|
{
|
2020-10-09 15:13:32 +08:00
|
|
|
|
if (SearchExpression != null)
|
2021-01-07 00:41:26 +08:00
|
|
|
|
treeNode.Matched = SearchExpression(treeNode);
|
2020-10-09 15:13:32 +08:00
|
|
|
|
else
|
2021-01-07 00:41:26 +08:00
|
|
|
|
treeNode.Matched = treeNode.Title.Contains(SearchValue);
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
var hasChildMatched = treeNode.Matched;
|
2020-10-09 15:13:32 +08:00
|
|
|
|
foreach (var item in treeNode.ChildNodes)
|
2020-06-29 23:24:21 +08:00
|
|
|
|
{
|
2020-10-09 15:13:32 +08:00
|
|
|
|
var itemMatched = SearchNode(item);
|
|
|
|
|
hasChildMatched = hasChildMatched || itemMatched;
|
2020-06-29 23:24:21 +08:00
|
|
|
|
}
|
2020-10-09 15:13:32 +08:00
|
|
|
|
treeNode.HasChildMatched = hasChildMatched;
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
return hasChildMatched;
|
2020-06-29 23:24:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
#endregion Search
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
#region DataBind
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public IList<TItem> DataSource { get; set; }
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 指定一个方法,该表达式返回节点的文本。
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public Func<TreeNode<TItem>, string> TitleExpression { get; set; }
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 指定一个返回节点名称的方法。
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public Func<TreeNode<TItem>, string> KeyExpression { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 指定一个返回节点名称的方法。
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public Func<TreeNode<TItem>, string> IconExpression { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 返回一个值是否是页节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public Func<TreeNode<TItem>, bool> IsLeafExpression { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 返回子节点的方法
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public Func<TreeNode<TItem>, IList<TItem>> ChildrenExpression { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
#endregion DataBind
|
2020-06-29 23:24:21 +08:00
|
|
|
|
|
2020-10-09 15:13:32 +08:00
|
|
|
|
#region Event
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 延迟加载
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>必须使用async,且返回类型为Task,否则可能会出现载入时差导致显示问题</remarks>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public EventCallback<TreeEventArgs<TItem>> OnNodeLoadDelayAsync { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 点击树节点触发
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public EventCallback<TreeEventArgs<TItem>> OnClick { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 双击树节点触发
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public EventCallback<TreeEventArgs<TItem>> OnDblClick { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 右键树节点触发
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public EventCallback<TreeEventArgs<TItem>> OnContextMenu { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 点击树节点 Checkbox 触发
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public EventCallback<TreeEventArgs<TItem>> OnCheckBoxChanged { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 点击展开树节点图标触发
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public EventCallback<TreeEventArgs<TItem>> OnExpandChanged { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 搜索节点时调用(与SearchValue配合使用)
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public EventCallback<TreeEventArgs<TItem>> OnSearchValueChanged { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// 开始拖拽时调用
|
|
|
|
|
///// </summary>
|
|
|
|
|
//public EventCallback<TreeEventArgs> OnDragStart { get; set; }
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// dragenter 触发时调用
|
|
|
|
|
///// </summary>
|
|
|
|
|
//public EventCallback<TreeEventArgs> OnDragEnter { get; set; }
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// dragover 触发时调用
|
|
|
|
|
///// </summary>
|
|
|
|
|
//public EventCallback<TreeEventArgs> OnDragOver { get; set; }
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// dragleave 触发时调用
|
|
|
|
|
///// </summary>
|
|
|
|
|
//public EventCallback<TreeEventArgs> OnDragLeave { get; set; }
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// drop 触发时调用
|
|
|
|
|
///// </summary>
|
|
|
|
|
//public EventCallback<TreeEventArgs> OnDrop { get; set; }
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// dragend 触发时调用
|
|
|
|
|
///// </summary>
|
|
|
|
|
//public EventCallback<TreeEventArgs> OnDragEnd { get; set; }
|
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
#endregion Event
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
#region Template
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 缩进模板
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public RenderFragment<TreeNode<TItem>> IndentTemplate { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 标题模板
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public RenderFragment<TreeNode<TItem>> TitleTemplate { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 图标模板
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public RenderFragment<TreeNode<TItem>> TitleIconTemplate { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 切换图标模板
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter]
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public RenderFragment<TreeNode<TItem>> SwitcherIconTemplate { get; set; }
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
#endregion Template
|
|
|
|
|
|
|
|
|
|
protected override void OnInitialized()
|
|
|
|
|
{
|
|
|
|
|
SetClassMapper();
|
|
|
|
|
base.OnInitialized();
|
|
|
|
|
}
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
2020-10-21 13:51:41 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Find Node
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="predicate">Predicate</param>
|
|
|
|
|
/// <param name="recursive">Recursive Find</param>
|
|
|
|
|
/// <returns></returns>
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public TreeNode<TItem> FindFirstOrDefaultNode(Func<TreeNode<TItem>, bool> predicate, bool recursive = true)
|
2020-10-21 13:51:41 +08:00
|
|
|
|
{
|
|
|
|
|
foreach (var child in ChildNodes)
|
|
|
|
|
{
|
2021-01-07 00:41:26 +08:00
|
|
|
|
if (predicate != null && predicate.Invoke(child))
|
2020-10-21 13:51:41 +08:00
|
|
|
|
{
|
|
|
|
|
return child;
|
|
|
|
|
}
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
2020-10-21 13:51:41 +08:00
|
|
|
|
if (recursive)
|
|
|
|
|
{
|
|
|
|
|
var find = child.FindFirstOrDefaultNode(predicate, recursive);
|
|
|
|
|
if (find != null)
|
|
|
|
|
{
|
|
|
|
|
return find;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2021-01-07 00:41:26 +08:00
|
|
|
|
|
2020-10-21 13:51:41 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// from node expand to root
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="node">Node</param>
|
2020-12-30 18:38:35 +08:00
|
|
|
|
public void ExpandToNode(TreeNode<TItem> node)
|
2020-10-21 13:51:41 +08:00
|
|
|
|
{
|
|
|
|
|
if (node == null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException(nameof(node));
|
|
|
|
|
}
|
|
|
|
|
var parentNode = node.ParentNode;
|
|
|
|
|
while (parentNode != null)
|
|
|
|
|
{
|
|
|
|
|
parentNode.Expand(true);
|
|
|
|
|
parentNode = parentNode.ParentNode;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 展开全部节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void ExpandAll()
|
|
|
|
|
{
|
|
|
|
|
this.ChildNodes.ForEach(node => Switch(node, true));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 折叠全部节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void CollapseAll()
|
|
|
|
|
{
|
|
|
|
|
this.ChildNodes.ForEach(node => Switch(node, false));
|
|
|
|
|
}
|
2020-10-09 15:13:32 +08:00
|
|
|
|
|
2021-01-07 00:41:26 +08:00
|
|
|
|
private void Switch(TreeNode<TItem> node, bool expanded)
|
2020-10-09 15:13:32 +08:00
|
|
|
|
{
|
2021-01-07 00:41:26 +08:00
|
|
|
|
node.Expand(expanded);
|
|
|
|
|
node.ChildNodes.ForEach(n => Switch(n, expanded));
|
2020-10-09 15:13:32 +08:00
|
|
|
|
}
|
2020-06-29 15:39:18 +08:00
|
|
|
|
}
|
|
|
|
|
}
|