Enterprise-level component library based on Bootstrap and Blazor

star nuget master download license repo commit

Tree 树形控件

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

基础用法

基础的树形结构展示

Demo

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

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

可选择

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

Demo

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

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

禁用状态

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

Demo

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

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

手风琴模式

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

Demo

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

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

默认展开和默认选中

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

Demo

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

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

显示图标

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

Demo

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

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

点击节点展开收缩功能

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

Demo

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

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

Attributes

Loading...

TreeItem 属性

Loading...
@page "/trees"

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

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

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

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

<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 System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

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

        private Logger? TraceChecked { get; set; }

        private static IEnumerable<TreeItem> GetItems()
        {
            var ret = new List<TreeItem>
            {
                new TreeItem() { Text = "导航一" },
                new TreeItem() { Text = "导航二" },
                new TreeItem() { Text = "导航三" }
            };

            ret[0].AddItem(new TreeItem() { Text = "子菜单" });

            ret[1].AddItem(new TreeItem() { Text = "子菜单一" });
            ret[1].AddItem(new TreeItem() { Text = "子菜单二" });
            ret[1].AddItem(new TreeItem() { Text = "子菜单三" });

            ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1一" });
            ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1二" });

            ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2一" });
            ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2二" });

            ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单一" });
            ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单二" });

            ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单一" });
            ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单二" });

            return ret;
        }

        private IEnumerable<TreeItem> Items { get; set; } = GetItems();

        private static IEnumerable<TreeItem> GetCheckedItems()
        {
            var ret = new List<TreeItem>
            {
                new TreeItem() { Text = "导航一" },
                new TreeItem() { Text = "导航二", Checked = true, IsExpanded = true },
                new TreeItem() { Text = "导航三" }
            };

            ret[1].AddItem(new TreeItem() { Text = "子菜单一" });
            ret[1].AddItem(new TreeItem() { Text = "子菜单二", IsExpanded = true });
            ret[1].AddItem(new TreeItem() { Text = "子菜单三" });

            ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1一" });
            ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1二" });

            ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2一" });
            ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2二" });

            ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单一" });
            ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单二" });

            ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单一" });
            ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单二" });

            return ret;
        }

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

        private static IEnumerable<TreeItem> GetDisabledItems()
        {
            var ret = new List<TreeItem>
            {
                new TreeItem() { Text = "导航一" },
                new TreeItem() { Text = "导航二", Disabled = true },
                new TreeItem() { Text = "导航三" }
            };

            ret[1].AddItem(new TreeItem() { Text = "子菜单一" });
            ret[1].AddItem(new TreeItem() { Text = "子菜单二" });
            ret[1].AddItem(new TreeItem() { Text = "子菜单三" });

            ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1一" });
            ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1二" });

            ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2一" });
            ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2二" });

            ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单一" });
            ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单二" });

            ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单一" });
            ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单二" });

            return ret;
        }

        private static IEnumerable<TreeItem> GetIconItems()
        {
            var ret = new List<TreeItem>
            {
                new TreeItem() { Text = "导航一", Icon = "fa fa-fa fa-fw" },
                new TreeItem() { Text = "导航二", Icon = "fa fa-fa fa-fw" },
                new TreeItem() { Text = "导航三", Icon = "fa fa-fa fa-fw" }
            };

            ret[1].AddItem(new TreeItem() { Text = "子菜单一", Icon = "fa fa-fa fa-fw" });
            ret[1].AddItem(new TreeItem() { Text = "子菜单二", Icon = "fa fa-fa fa-fw" });
            ret[1].AddItem(new TreeItem() { Text = "子菜单三", Icon = "fa fa-fa fa-fw" });

            return ret;
        }

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

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

        /// <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 = " — "
            }
        };

        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 = "Disabled",
                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 = " — "
            },
        };
    }
}

B 站相关视频链接

暂无

交流群

QQ群: BootstrapAdmin & Blazor(795206915)欢迎加群讨论
An error has occurred. This application may no longer respond until reloaded. Reload