Enterprise-level component library based on Bootstrap and Blazor

star nuget master download license repo commit

Tree 树形控件

用清晰的层级结构展示信息,可展开或折叠

基础的树形结构展示

Demo

通过设置 OnTreeItemClick 属性监控树形控件节点被点击时的事件,点击树形控件节点时下面日志显示选中节点的数据

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

适用于需要选择层级时使用

Demo

通过设置 OnTreeItemChecked 属性监控树形控件节点被勾选时的事件,选中树形控件节点前复选框时下面日志显示选中节点的数据

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

可将 Tree 的某些节点设置为禁用状态

Demo

通过设置数据源 TreeItem 对象的 Disabled 属性,来控制此节点是否可以进行勾选动作,设置为 false 时不影响节点展开/收缩功能

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

对于同一级的节点,每次只能展开一个

Demo

通过设置 Tree 组件的 IsAccordion 属性开启手风琴效果

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

可将 Tree 的某些节点设置为默认展开或默认选中

Demo

通过设置 TreeItem 对象的 IsExpanded 属性,来控制此节点是否默认为展开状态,本例中 导航二子菜单二 默认为展开状态,其余节点默认为收缩状态

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

通过设置 ShowIcon 来控制组件是否显示图标

Demo

通过设置 TreeItem 对象的 ShowIcon 属性,来控制此节点是否显示图标

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

通过设置 ClickToggleNode 来控制点击节点时是否进行展开收缩操作

Demo

通过设置 TreeItem 对象的 ClickToggleNode 属性,来控制此节点是否通过点击来实现展开收缩操作

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

Tree 组件内部可开启 Checkbox 内置到验证表单时会显示 DisplayName 此功能在树状组件内需要禁止

Demo

通过设置 ShowCheckbox 属性显示 Checkbox 内置到验证组件 ValidateForm 中不显示 DisplayName

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

展开节点时动态添加子节点

Demo

通过设置节点 HasChildNode 控制是否显示节点小箭头图片 。通过Tree的 OnExpandNode 委托添加节点

  • 导航一
  • 导航二
    • 子菜单一
    • 懒加载
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 懒加载延时
  • 导航三

通过设置 TreeItem Template 来实现自己的节点模板

Demo
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

Attributes

Loading...

TreeItem 属性

Loading...
@page "/trees"

<h3>Tree 树形控件</h3>

<h4>用清晰的层级结构展示信息,可展开或折叠</h4>

<Block Title="基础用法" Introduction="基础的树形结构展示">
    <p>
        通过设置 <code>OnTreeItemClick</code> 属性监控树形控件节点被点击时的事件,点击树形控件节点时下面日志显示选中节点的数据
    </p>
    <Tree Items="@Items" OnTreeItemClick="@OnTreeItemClick" />
    <BlockLogger @ref="Trace" class="mt-3" />
</Block>

<Block Title="可选择" Introduction="适用于需要选择层级时使用">
    <p>
        通过设置 <code>OnTreeItemChecked</code> 属性监控树形控件节点被勾选时的事件,选中树形控件节点前复选框时下面日志显示选中节点的数据
    </p>
    <Tree Items="@CheckedItems" ShowCheckbox="true" OnTreeItemChecked="@OnTreeItemChecked" />
    <BlockLogger @ref="TraceChecked" class="mt-3" />
</Block>

<Block Title="禁用状态" Introduction="可将 Tree 的某些节点设置为禁用状态">
    <p>
        通过设置数据源 <code>TreeItem</code> 对象的 <code>Disabled</code> 属性,来控制此节点是否可以进行勾选动作,设置为 <code>false</code> 时不影响节点展开/收缩功能
    </p>
    <Tree Items="@DisabledItems" ShowCheckbox="true" />
</Block>

<Block Title="手风琴模式" Introduction="对于同一级的节点,每次只能展开一个">
    <p>通过设置 <code>Tree</code> 组件的 <code>IsAccordion</code> 属性开启手风琴效果</p>
    <Tree Items="@Items" ShowCheckbox="true" IsAccordion="true" />
</Block>

<Block Title="默认展开和默认选中" Introduction="可将 <code>Tree</code> 的某些节点设置为默认展开或默认选中">
    <p>
        通过设置 <code>TreeItem</code> 对象的 <code>IsExpanded</code> 属性,来控制此节点是否默认为展开状态,本例中 <b>导航二</b> 与 <b>子菜单二</b> 默认为展开状态,其余节点默认为收缩状态
    </p>
    <Tree Items="@CheckedItems" ShowCheckbox="true" />
</Block>

<Block Title="显示图标" Introduction="通过设置 <code>ShowIcon</code> 来控制组件是否显示图标">
    <p>
        通过设置 <code>TreeItem</code> 对象的 <code>ShowIcon</code> 属性,来控制此节点是否显示图标
    </p>
    <Tree Items="@GetIconItems()" ShowIcon="true" ShowCheckbox="true" />
</Block>

<Block Title="点击节点展开收缩功能" Introduction="通过设置 <code>ClickToggleNode</code> 来控制点击节点时是否进行展开收缩操作">
    <p>
        通过设置 <code>TreeItem</code> 对象的 <code>ClickToggleNode</code> 属性,来控制此节点是否通过点击来实现展开收缩操作
    </p>
    <Tree Items="@Items" ShowIcon="true" ShowCheckbox="true" ClickToggleNode="true" />
</Block>

<Block Title="Tree 组件内置到验证表单中" Introduction="<code>Tree</code> 组件内部可开启 <code>Checkbox</code> 内置到验证表单时会显示 <code>DisplayName</code> 此功能在树状组件内需要禁止">
    <p>
        通过设置 <code>ShowCheckbox</code> 属性显示 <code>Checkbox</code> 内置到验证组件 <code>ValidateForm</code> 中不显示 <code>DisplayName</code>
    </p>
    <ValidateForm Model="@Model">
        <Tree Items="@Items" OnTreeItemClick="@OnTreeItemClick" ShowCheckbox="true" />
    </ValidateForm>
</Block>

<Block Title="懒加载" Introduction="展开节点时动态添加子节点">
    <p>
        通过设置节点 <code>HasChildNode</code> 控制是否显示节点小箭头图片 。通过Tree的 <code>OnExpandNode</code> 委托添加节点
    </p>
    <Tree ClickToggleNode="true" Items="@GetLazyItems()" OnExpandNode="OnExpandNode" />
</Block>

<Block Title="自定义节点" Introduction="通过设置 <code>TreeItem</code> <code>Template</code> 来实现自己的节点模板">
    <Tree ClickToggleNode="true" Items="GetTemplateItems()" />
</Block>

<AttributeTable Items="@GetAttributes()" />

<AttributeTable Items="@GetTreeItemAttributes()" Title="TreeItem 属性" />
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using BootstrapBlazor.Components;
using BootstrapBlazor.Shared.Common;
using BootstrapBlazor.Shared.Pages.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Localization;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;

namespace BootstrapBlazor.Shared.Pages
{
    /// <summary>
    /// 
    /// </summary>
    public sealed partial class Trees
    {
        [NotNull]
        private BlockLogger? Trace { get; set; }

        [NotNull]
        private BlockLogger? TraceChecked { get; set; }

        [Inject]
        [NotNull]
        private IStringLocalizer<Foo>? Localizer { get; set; }

        private Foo Model => Foo.Generate(Localizer);

        private List<TreeItem> Items { get; set; } = TreeDataFoo.GetTreeItems();

        private List<TreeItem> CheckedItems { get; set; } = GetCheckedItems();

        private static List<TreeItem> GetCheckedItems()
        {
            var ret = TreeDataFoo.GetTreeItems();
            ret[1].Items[1].Checked = true;
            return ret;
        }

        private List<TreeItem> DisabledItems { get; set; } = GetDisabledItems();

        private static List<TreeItem> GetDisabledItems()
        {
            var ret = TreeDataFoo.GetTreeItems();
            ret[1].Items[1].IsDisabled = true;
            return ret;
        }

        private static List<TreeItem> GetIconItems()
        {
            var ret = TreeDataFoo.GetTreeItems();
            ret[1].Items[0].Icon = "fa fa-fa";
            ret[1].Items[1].Icon = "fa fa-fa";
            ret[1].Items[2].Icon = "fa fa-fa";
            return ret;
        }

        private static List<TreeItem> GetLazyItems()
        {
            var ret = TreeDataFoo.GetTreeItems();
            ret[1].Items[0].IsExpanded = true;
            ret[1].Items[1].Text = "懒加载";
            ret[1].Items[1].HasChildNode = true;
            ret[1].Items[2].Text = "懒加载延时";
            ret[1].Items[2].HasChildNode = true;
            ret[1].Items[2].Key = "Delay";

            return ret;
        }

        private static List<TreeItem> GetTemplateItems()
        {
            var ret = TreeDataFoo.GetTreeItems();
            ret[0].Template = BootstrapDynamicComponent.CreateComponent<CustomerTreeItem>().Render();
            return ret;
        }

        private class CustomerTreeItem : ComponentBase
        {
            [Inject]
            [NotNull]
            private ToastService? ToastService { get; set; }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="builder"></param>
            protected override void BuildRenderTree(RenderTreeBuilder builder)
            {
                builder.OpenComponent<Button>(0);
                builder.AddAttribute(1, nameof(Button.Icon), "fa fa-fa");
                builder.AddAttribute(2, nameof(Button.Text), "Click");
                builder.AddAttribute(3, nameof(Button.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, e =>
                {
                    ToastService.Warning("自定义 TreeItem", "测试 TreeItem 按钮点击事件");
                }));
                builder.CloseComponent();
            }
        }

        private Task OnTreeItemClick(TreeItem item)
        {
            Trace.Log($"TreeItem: {item.Text} clicked");
            return Task.CompletedTask;
        }

        private Task OnTreeItemChecked(TreeItem item)
        {
            var state = item.Checked ? "选中" : "未选中";
            TraceChecked.Log($"TreeItem: {item.Text} {state}");
            return Task.CompletedTask;
        }

        private static async Task OnExpandNode(TreeItem item)
        {
            if (!item.Items.Any() && item.HasChildNode && !item.ShowLoading)
            {
                item.ShowLoading = true;
                if (item.Key?.ToString() == "Delay")
                {
                    await Task.Delay(800);
                }
                item.Items.AddRange(new TreeItem[]
                {
                    new TreeItem()
                    {
                        Text = "懒加载子节点1",
                        HasChildNode = true
                    },
                    new TreeItem() { Text = "懒加载子节点2" }
                });
                item.ShowLoading = false;
            }
        }

        /// <summary>
        /// 获得属性方法
        /// </summary>
        /// <returns></returns>
        private static IEnumerable<AttributeItem> GetAttributes() => new AttributeItem[]
        {
            // TODO: 移动到数据库中
            new AttributeItem() {
                Name = "Items",
                Description = "菜单数据集合",
                Type = "IEnumerable<TreeItem>",
                ValueList = " — ",
                DefaultValue = "new List<TreeItem>(20)"
            },
            new AttributeItem() {
                Name = "ClickToggleNode",
                Description = "是否点击节点时展开或者收缩子项",
                Type = "bool",
                ValueList = "true|false",
                DefaultValue = "false"
            },
            new AttributeItem() {
                Name = "ShowCheckbox",
                Description = "是否显示 CheckBox",
                Type = "bool",
                ValueList = "true|false",
                DefaultValue = "false"
            },
            new AttributeItem() {
                Name = "ShowIcon",
                Description = "是否显示 Icon",
                Type = "bool",
                ValueList = "true|false",
                DefaultValue = "false"
            },
            new AttributeItem() {
                Name = "ShowSkeleton",
                Description = "是否显示加载骨架屏",
                Type = "bool",
                ValueList = "true|false",
                DefaultValue = "false"
            },
            new AttributeItem() {
                Name = "OnTreeItemClick",
                Description = "树形控件节点点击时回调委托",
                Type = "Func<TreeItem, Task>",
                ValueList = " — ",
                DefaultValue = " — "
            },
            new AttributeItem() {
                Name = "OnTreeItemChecked",
                Description = "树形控件节点选中时回调委托",
                Type = "Func<TreeItem, Task>",
                ValueList = " — ",
                DefaultValue = " — "
            },
            new AttributeItem() {
                Name = "OnExpandNode",
                Description = "树形控件节点展开回调委托",
                Type = "Func<TreeItem, Task>",
                ValueList = " — ",
                DefaultValue = " — "
            }
        };

        private static IEnumerable<AttributeItem> GetTreeItemAttributes() => new AttributeItem[]
        {
            // TODO: 移动到数据库中
            new AttributeItem() {
                Name = nameof(TreeItem.Key),
                Description = "TreeItem 标识",
                Type = "object?",
                ValueList = " — ",
                DefaultValue = " — "
            },
            new AttributeItem() {
                Name = "Items",
                Description = "子节点数据源",
                Type = "IEnumerable<TreeItem>",
                ValueList = " — ",
                DefaultValue = "new List<TreeItem>(20)"
            },
            new AttributeItem() {
                Name = "Text",
                Description = "显示文字",
                Type = "string",
                ValueList = " — ",
                DefaultValue = " — "
            },
            new AttributeItem() {
                Name = "Icon",
                Description = "显示图标",
                Type = "string",
                ValueList = " — ",
                DefaultValue = " — "
            },
            new AttributeItem() {
                Name = "Checked",
                Description = "是否被选中",
                Type = "bool",
                ValueList = "true|false",
                DefaultValue = "false"
            },
            new AttributeItem() {
                Name = nameof(TreeItem.IsDisabled),
                Description = "是否被禁用",
                Type = "bool",
                ValueList = "true|false",
                DefaultValue = "false"
            },
            new AttributeItem() {
                Name = "IsExpanded",
                Description = "是否展开",
                Type = "bool",
                ValueList = "true|false",
                DefaultValue = "false"
            },
            new AttributeItem() {
                Name = nameof(TreeItem.Tag),
                Description = "TreeItem 附加数据",
                Type = "object?",
                ValueList = " — ",
                DefaultValue = " — "
            },
            new AttributeItem() {
                Name = nameof(TreeItem.HasChildNode),
                Description = "是否有子节点",
                Type = "bool",
                ValueList = " true|false ",
                DefaultValue = " false "
            },
            new AttributeItem() {
                Name = nameof(TreeItem.ShowLoading),
                Description = "是否显示子节点加载动画",
                Type = "bool",
                ValueList = " true|false ",
                DefaultValue = " false "
            },
            new AttributeItem()
            {
                Name = nameof(TreeItem.Template),
                Description = "子节点模板",
                Type = nameof(RenderFragment),
                ValueList = " — ",
                DefaultValue = " — "
            }
        };
    }
}

B 站相关视频链接

暂无

交流群

QQ Group:BootstrapAdmin & Blazor 795206915( Full) 675147445 Welcome to join the group discussion
Themes
Bootstrap
Ant Design (完善中)
Bluma (完善中)
LayUI (完善中)
Motronic (已集成)
An error has occurred. This application may no longer respond until reloaded. Reload