Enterprise-level component library based on Bootstrap and Blazor
gitee
version
license
download
repo
commit
build
coverage

Tree 树形控件

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

第一步:设置 TItem 泛型模型

第二步:设置 Items 获得组件数据源 注意 数据源类型为 IEnumerable<TreeItem<TItem>>

第三步:设置 OnExpandNodeAsync 回调委托响应节点展开获取子项数据源集合

第四步:设置 ModelEqualityComparer 提供组件识别模型比较委托方法,注意 本设置为可选项 通过上面讲解的回落机制进行降级搜索

基础的树形结构展示

Demo

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

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

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

Demo

通过设置 OnTreeItemChecked 属性监控树形控件节点被勾选时的事件,选中树形控件节点前复选框时下面日志显示选中节点的数据
Tree 组件数据加载内部将会保持各个节点状态,改变节点选中状态点击 刷新 按钮,组件节点状态保持不变,可通过参数 IsReset 强制数据重置

重置
保持
  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

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

Demo

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

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

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

Demo

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

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

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

Demo

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

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

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

Demo

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

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

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

Demo

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

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

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

Demo

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

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

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

Demo

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

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

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

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

通过设置 TreeItem CssClass 来实现自己的节点样式

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

通过设置 OnTreeItemChecked 回调委托获取所有节点

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

通过设置 ShowSkeleton 使异步加载数据时组件显示骨架屏

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

Attributes

Loading...

TreeItem 属性

Loading...
@page "/treeviews"

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

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

<Tips class="mt-3">
    <div><code>Tree</code> 组件为泛型组件需要使用 <code>TItem</code> 指定绑定的数据模型,本例中模型为 <code>TreeFoo</code> 需要设置 <code>TItem="TreeFoo"</code></div>
    <ul class="ul-demo mt-3">
        <li>设置 <code>TreeItem</code> 其 <code>IsExpand</code> 参数控制当前子节点是否展开</li>
        <li>点击子项展开小箭头时,通过 <code>OnExpandNodeAsync</code> 回调委托方法获取子项数据集合</li>
        <li>保持节点状态回落机制,<code>ModelEqualityComparer</code> <code>CustomKeyAttribute</code> <code>IEqualityComparer<TItem></code> <code>Equals</code> 重载方法</li>
        <li>组件将会保持 <code>展开</code> <code>收缩</code> <code>选中</code> 状态</li>
        <li>通过 <code>TreeItem<TItem>.IsExpand</code> 设置节点是否 <b>展开</b> 状态</li>
        <li>通过 <code>TreeItem<TItem>.IsActive</code> 设置节点是否 <b>选中</b> 状态</li>
        <li>通过 <code>TreeItem<TItem>.Checked</code> 设置节点是否 <b>复选/单选</b> 状态</li>
    </ul>
</Tips>

<p>第一步:设置 <code>TItem</code> 泛型模型</p>

<p>第二步:设置 <code>Items</code> 获得组件数据源 <b>注意</b> 数据源类型为 <code>IEnumerable<TreeItem<TItem>></code></p>

<p>第三步:设置 <code>OnExpandNodeAsync</code> 回调委托响应节点展开获取子项数据源集合</p>

<p>第四步:设置 <code>ModelEqualityComparer</code> 提供组件识别模型比较委托方法,<b>注意</b> 本设置为可选项 通过上面讲解的回落机制进行降级搜索</p>

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

<DemoBlock Title="多选框" Introduction="适用于需要选择层级时使用" Name="Checkbox">
    <p>
        <div>通过设置 <code>OnTreeItemChecked</code> 属性监控树形控件节点被勾选时的事件,选中树形控件节点前复选框时下面日志显示选中节点的数据</div>
        <div><code>Tree</code> 组件数据加载内部将会保持各个节点状态,改变节点选中状态点击 <b>刷新</b> 按钮,组件节点状态保持不变,可通过参数 <code>IsReset</code> 强制数据重置</div>
    </p>
    <div class="row form-inline">
        <div class="col-12 col-lg-auto">
            <RadioList IsButton="true" @bind-Value="@IsReset" Items="@ResetItems" Color="Color.Success" ShowLabel="true" DisplayText="是否重置"></RadioList>
        </div>
        <div class="col-12 col-lg-auto">
            <Checkbox DisplayText="自动选中子节点" ShowAfterLabel="true" @bind-Value="@AutoCheckChildren" />
            <Checkbox DisplayText="自动选中父节点" ShowAfterLabel="true" @bind-Value="@AutoCheckParent" class="ms-3" />
        </div>
        <div class="col-12 col-lg-auto">
            <Button Text="刷新" OnClick="OnRefresh" />
        </div>
    </div>
    <TreeView TItem="TreeFoo" Items="@CheckedItems" ShowCheckbox="true" OnTreeItemChecked="@OnTreeItemChecked" IsReset="@IsReset" AutoCheckChildren="@AutoCheckChildren" AutoCheckParent="@AutoCheckParent" />
    <BlockLogger @ref="TraceChecked" class="mt-3" />
</DemoBlock>

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

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

<DemoBlock Title="默认展开和默认选中" Introduction="可将 <code>Tree</code> 的某些节点设置为默认展开或默认选中" Name="DefauleExpand">
    <p>
        通过设置 <code>TreeItem</code> 对象的 <code>IsExpand</code> 属性,来控制此节点是否默认为展开状态,本例中 <b>导航二</b> 默认为展开状态,其余节点默认为收缩状态
    </p>
    <TreeView TItem="TreeFoo" Items="@ExpandItems" ShowCheckbox="true" />
</DemoBlock>

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

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

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

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

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

<DemoBlock Title="节点颜色" Introduction="通过设置 <code>TreeItem</code> <code>CssClass</code> 来实现自己的节点样式" Name="TreeNodeColor">
    <TreeView TItem="TreeFoo" ClickToggleNode="true" Items="GetColorItems()" />
</DemoBlock>

<DemoBlock Title="获取所有选中节点" Introduction="通过设置 <code>OnTreeItemChecked</code> 回调委托获取所有节点" Name="CheckedItems">
    <TreeView TItem="TreeFoo" ShowCheckbox="true" Items="@Items" OnTreeItemChecked="@OnTreeItemChecked" />
    <BlockLogger @ref="TraceCheckedItems" class="mt-3" />
</DemoBlock>

<DemoBlock Title="加载骨架屏" Introduction="通过设置 <code>ShowSkeleton</code> 使异步加载数据时组件显示骨架屏" Name="ShowSkeleton">
    <Button Text="异步加载" IsAsync="true" Icon="fa-solid fa-font-awesome" OnClick="OnLoadAsyncItems" />
    <TreeView TItem="TreeFoo" Items="@AsyncItems" ShowSkeleton="true" OnExpandNodeAsync="OnExpandNodeAsync" class="mt-3" />
</DemoBlock>

<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.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Localization;

namespace BootstrapBlazor.Shared.Samples;

/// <summary>
/// 
/// </summary>
public sealed partial class TreeViews
{
    [NotNull]
    private BlockLogger? Trace { get; set; }

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

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

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

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

    private List<TreeViewItem<TreeFoo>> Items { get; set; } = TreeFoo.GetTreeItems();

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

    private List<TreeViewItem<TreeFoo>> ExpandItems { get; set; } = GetExpandItems();

    private List<TreeViewItem<TreeFoo>>? AsyncItems { get; set; }

    [NotNull]
    private List<TreeViewItem<TreeFoo>>? SelectedItemsDataSource { get; set; }

    private bool AutoCheckChildren { get; set; }

    private bool AutoCheckParent { get; set; }

    private List<TreeViewItem<TreeFoo>> SelectedItems { get; set; } = new();

    private List<SelectedItem> ResetItems { get; } = new List<SelectedItem>()
    {
        new("True", "重置"),
        new("False", "保持")
    };

    /// <summary>
    /// OnInitializedAsync 方法
    /// </summary>
    /// <returns></returns>
    protected override async Task OnInitializedAsync()
    {
        await OnLoadAsyncItems();

        SelectedItemsDataSource = TreeFoo.GetTreeItems();
    }

    private void OnRefresh()
    {
        CheckedItems = GetCheckedItems();
    }

    private bool IsReset { get; set; }

    private async Task OnLoadAsyncItems()
    {
        AsyncItems = null;
        await Task.Delay(2000);
        AsyncItems = TreeFoo.GetTreeItems();
        AsyncItems[2].Text = "延时加载";
        AsyncItems[2].HasChildren = true;
    }

    private static List<TreeViewItem<TreeFoo>> GetCheckedItems()
    {
        var ret = TreeFoo.GetTreeItems();
        ret[1].IsActive = true;
        ret[1].Items[1].CheckedState = CheckboxState.Checked;
        return ret;
    }

    private static List<TreeViewItem<TreeFoo>> GetExpandItems()
    {
        var ret = TreeFoo.GetTreeItems();
        ret[1].IsExpand = true;
        return ret;
    }

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

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

    private static List<TreeViewItem<TreeFoo>> GetAccordionItems()
    {
        var ret = TreeFoo.GetTreeItems();
        ret[1].Items[0].HasChildren = true;
        return ret;
    }

    private static List<TreeViewItem<TreeFoo>> GetIconItems() => TreeFoo.GetTreeItems();

    private static List<TreeViewItem<TreeFoo>> GetLazyItems()
    {
        var ret = TreeFoo.GetTreeItems();
        ret[1].Items[0].IsExpand = true;
        ret[2].Text = "懒加载延时";
        ret[2].HasChildren = true;
        return ret;
    }

    private static List<TreeViewItem<TreeFoo>> GetTemplateItems()
    {
        var ret = TreeFoo.GetTreeItems();
        ret[0].Template = foo => BootstrapDynamicComponent.CreateComponent<CustomerTreeItem>(new Dictionary<string, object?>()
        {
            [nameof(CustomerTreeItem.Foo)] = foo
        }).Render();
        return ret;
    }

    private static List<TreeViewItem<TreeFoo>> GetColorItems()
    {
        var ret = TreeFoo.GetTreeItems();
        ret[0].CssClass = "text-primary";
        ret[1].CssClass = "text-success";
        ret[2].CssClass = "text-danger";
        return ret;
    }

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

        [Parameter]
        [NotNull]
        public TreeFoo? Foo { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="builder"></param>
        protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            builder.OpenElement(3, "span");
            builder.AddAttribute(4, "class", "me-3");
            builder.AddContent(5, Foo.Text);
            builder.CloseElement();

            builder.OpenComponent<Button>(0);
            builder.AddAttribute(1, nameof(Button.Icon), "fa-solid fa-font-awesome");
            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(TreeViewItem<TreeFoo> item)
    {
        Trace.Log($"TreeItem: {item.Text} clicked");
        return Task.CompletedTask;
    }

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

    private static async Task<IEnumerable<TreeViewItem<TreeFoo>>> OnExpandNodeAsync(TreeViewItem<TreeFoo> node)
    {
        await Task.Delay(800);
        var item = node.Value;
        return new TreeViewItem<TreeFoo>[]
        {
            new TreeViewItem<TreeFoo>(new TreeFoo() { Id = $"{item.Id}-101", ParentId = item.Id })
            {
                Text = "懒加载子节点1",
                HasChildren = true
            },
            new TreeViewItem<TreeFoo>(new TreeFoo(){ Id = $"{item.Id}-102", ParentId = item.Id })
            {
                Text = "懒加载子节点2"
            }
        };
    }

    private Task OnTreeItemChecked(List<TreeViewItem<TreeFoo>> items)
    {
        TraceCheckedItems.Log($"当前共选中{items.Count}项");
        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 = nameof(TreeView<string>.OnTreeItemClick),
            Description = "树形控件节点点击时回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeView<string>.OnTreeItemChecked),
            Description = "树形控件节点选中时回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeView<string>.OnExpandNodeAsync),
            Description = "树形控件节点展开回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        }
    };

    private static IEnumerable<AttributeItem> GetTreeItemAttributes() => new AttributeItem[]
    {
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.Items),
            Description = "子节点数据源",
            Type = "List<TreeItem<TItem>>",
            ValueList = " — ",
            DefaultValue = "new ()"
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.Text),
            Description = "显示文字",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.Icon),
            Description = "显示图标",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.CssClass),
            Description = "节点自定义样式",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.CheckedState),
            Description = "是否被选中",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.IsDisabled),
            Description = "是否被禁用",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.IsExpand),
            Description = "是否展开",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "true"
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.HasChildren),
            Description = "是否有子节点",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.ShowLoading),
            Description = "是否显示子节点加载动画",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem()
        {
            Name = nameof(TreeViewItem<TreeFoo>.Template),
            Description = "子节点模板",
            Type = nameof(RenderFragment),
            ValueList = " — ",
            DefaultValue = " — "
        }
    };
}

B 站相关视频链接

暂无

交流群

QQ Group:BootstrapAdmin & Blazor 795206915 675147445 Welcome to join the group discussion
Themes
Bootstrap
Motronic
Ant Design (完善中)
DevUI (制作中)
LayUI (完善中)
An error has occurred. This application may no longer respond until reloaded. Reload
Seems like the connection with the server has been lost. It can be due to poor or broken network. Please hang on while we're trying to reconnect...
Oh snap! Failed to reconnect with the server. This is typically caused by a longer network outage, or if the server has been taken down. You can try to reconnect, but if that does not work, you need to reload the page.
Oh man! The server rejected the attempt to reconnect. The only option now is to reload the page, but be prepared that it won't work, since this is typically caused by a failure on the server.
Bootstrap Blazor 组件库 更新到 6.6.0

首先感谢您对本套组件的关注,目前本套组件已经拥有超过 120 个组件,本组件是基于 Bootstrap 风格的 Blazor 企业级组件库,提供如布局、导航、表单、数据、通知、图标、语音等几大类通用组件,每一个组件都经过静心设计,具有模块化、响应式和优秀的性能。从更多实际场景出发,满足多种场景的需求,极大的减少开发者时间成本,大大缩短开发周期,大幅提高开发效率,并提供了一套 通用权限管理系统 示例工程。Bootstrap Blazor 产品是由一支专业的全职技术团队进行维护,高效的响应速度,多元化的解决方案,长期提供支持,并提供企业级支持。目前已在多家知名国企内部使用,项目最高在线 1200 人稳定运行。右侧为国内人数最多的中文 Blazor QQ 社区二维码,欢迎扫描加群。

组件更新到 6.6.0 更新日志 [传送门] 如果组件给您带来了方便,请您帮忙给项目点亮 Star github gitee

QQGroup
QQ 795206915