using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; namespace AntDesign { public partial class Tree : AntDomComponentBase { #region Tree /// /// 节点前添加展开图标 /// [Parameter] public bool ShowExpand { get; set; } = true; /// /// 是否展示连接线 /// [Parameter] public bool ShowLine { get; set; } /// /// 是否展示 TreeNode title 前的图标 /// [Parameter] public bool ShowIcon { get; set; } /// /// 是否节点占据一行 /// [Parameter] public bool BlockNode { get; set; } /// /// 设置节点可拖拽 /// [Parameter] public bool Draggable { get; set; } 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); } #endregion #region Node [Parameter] public RenderFragment Nodes { get; set; } [Parameter] public List ChildNodes { get; set; } = new List(); /// /// 添加节点 /// /// /// internal void AddNode(TreeNode treeNode) { ChildNodes.Add(treeNode); } #endregion #region Selected /// /// 支持点选多个节点(节点本身) /// [Parameter] public bool Multiple { get; set; } /// /// 选中的树节点 /// internal Dictionary SelectedNodesDictionary { get; set; } = new Dictionary(); public List SelectedNodes => SelectedNodesDictionary.Select(x => x.Value).ToList(); public List SelectedNames => SelectedNodesDictionary.Select(x => x.Value.Name).ToList(); public List SelectedTitles => SelectedNodesDictionary.Select(x => x.Value.Title).ToList(); internal void SelectedNodeAdd(TreeNode treeNodes) { if (SelectedNodesDictionary.ContainsKey(treeNodes.NodeId) == false) SelectedNodesDictionary.Add(treeNodes.NodeId, treeNodes); } internal void SelectedNodeRemove(TreeNode treeNodes) { if (SelectedNodesDictionary.ContainsKey(treeNodes.NodeId) == true) SelectedNodesDictionary.Remove(treeNodes.NodeId); } public void DeselectAll() { foreach (var item in SelectedNodesDictionary.Select(x => x.Value).ToList()) { item.SetSelected(false); } } #endregion #region Checkable /// /// 节点前添加 Checkbox 复选框 /// [Parameter] public bool Checkable { get; set; } public List CheckedNodes => GetCheckedNodes(ChildNodes); public List CheckedNames => GetCheckedNodes(ChildNodes).Select(x => x.Name).ToList(); public List CheckedTitles => GetCheckedNodes(ChildNodes).Select(x => x.Title).ToList(); private List GetCheckedNodes(List childs) { List checkeds = new List(); foreach (var item in childs) { if (item.IsChecked) checkeds.Add(item); checkeds.AddRange(GetCheckedNodes(item.ChildNodes)); } return checkeds; } //取消所有选择项目 public void DecheckedAll() { foreach (var item in ChildNodes) { item.SetChecked(false); } } #endregion #region Search public string _searchValue; /// /// 按需筛选树,双向绑定 /// [Parameter] public string SearchValue { get => _searchValue; set { if (_searchValue == value) return; _searchValue = value; if (string.IsNullOrEmpty(value)) return; foreach (var item in ChildNodes) { SearchNode(item); } } } /// /// 返回一个值是否是页节点 /// [Parameter] public Func SearchExpression { get; set; } /// /// 查询节点 /// /// /// private bool SearchNode(TreeNode treeNode) { if (SearchExpression != null) treeNode.IsMatched = SearchExpression(treeNode); else treeNode.IsMatched = treeNode.Title.Contains(SearchValue); var hasChildMatched = treeNode.IsMatched; foreach (var item in treeNode.ChildNodes) { var itemMatched = SearchNode(item); hasChildMatched = hasChildMatched || itemMatched; } treeNode.HasChildMatched = hasChildMatched; return hasChildMatched; } #endregion #region DataBind [Parameter] public IEnumerable DataSource { get; set; } /// /// 指定一个方法,该表达式返回节点的文本。 /// [Parameter] public Func TitleExpression { get; set; } /// /// 指定一个返回节点名称的方法。 /// [Parameter] public Func NameExpression { get; set; } /// /// 指定一个返回节点名称的方法。 /// [Parameter] public Func IconExpression { get; set; } /// /// 返回一个值是否是页节点 /// [Parameter] public Func IsLeafExpression { get; set; } /// /// 返回子节点的方法 /// [Parameter] public Func ChildrenExpression { get; set; } #endregion #region Event /// /// 延迟加载 /// /// 必须使用async,且返回类型为Task,否则可能会出现载入时差导致显示问题 [Parameter] public EventCallback OnNodeLoadDelayAsync { get; set; } /// /// 点击树节点触发 /// [Parameter] public EventCallback OnClick { get; set; } /// /// 双击树节点触发 /// [Parameter] public EventCallback OnDblClick { get; set; } /// /// 右键树节点触发 /// [Parameter] public EventCallback OnContextMenu { get; set; } /// /// 点击树节点 Checkbox 触发 /// [Parameter] public EventCallback OnCheckBoxChanged { get; set; } /// /// 点击展开树节点图标触发 /// [Parameter] public EventCallback OnExpandChanged { get; set; } /// /// 搜索节点时调用(与SearchValue配合使用) /// [Parameter] public EventCallback OnSearchValueChanged { get; set; } ///// ///// 开始拖拽时调用 ///// //public EventCallback OnDragStart { get; set; } ///// ///// dragenter 触发时调用 ///// //public EventCallback OnDragEnter { get; set; } ///// ///// dragover 触发时调用 ///// //public EventCallback OnDragOver { get; set; } ///// ///// dragleave 触发时调用 ///// //public EventCallback OnDragLeave { get; set; } ///// ///// drop 触发时调用 ///// //public EventCallback OnDrop { get; set; } ///// ///// dragend 触发时调用 ///// //public EventCallback OnDragEnd { get; set; } #endregion #region Template /// /// 缩进模板 /// [Parameter] public RenderFragment IndentTemplate { get; set; } /// /// 标题模板 /// [Parameter] public RenderFragment TitleTemplate { get; set; } /// /// 图标模板 /// [Parameter] public RenderFragment TitleIconTemplate { get; set; } /// /// 切换图标模板 /// [Parameter] public RenderFragment SwitcherIconTemplate { get; set; } #endregion /// /// Find Node /// /// Predicate /// Recursive Find /// public TreeNode FindFirstOrDefaultNode(Func predicate, bool recursive = true) { foreach (var child in ChildNodes) { if (predicate.Invoke(child)) { return child; } if (recursive) { var find = child.FindFirstOrDefaultNode(predicate, recursive); if (find != null) { return find; } } } return null; } /// /// from node expand to root /// /// Node public void ExpandToNode(TreeNode node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } var parentNode = node.ParentNode; while (parentNode != null) { parentNode.Expand(true); parentNode = parentNode.ParentNode; } } protected override void OnInitialized() { SetClassMapper(); base.OnInitialized(); } } }