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

Tree tree control

Present information in a clear hierarchy that can be expanded or collapsed

Step 1: Set the TItem generic model

Step 2: Set Items to get the component data source Note The data source type is IEnumerable<TreeItem<TItem>>

Step 3: Set the OnExpandNodeAsync callback delegate to expand the response node to get the child data source collection

Step 4: Set ModelEqualityComparer to provide a component identification model comparison delegate method, Note This setting is optional. Perform downgrade search through the fallback mechanism explained above

Basic tree structure display

Demo

By setting the OnTreeItemClick property to monitor the event when the tree control node is clicked, the following log displays the data of the selected node when the tree control node is clicked

  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

Suitable for use when you need to select a level

Demo

By setting the OnTreeItemChecked property to monitor the event when the tree control node is checked, when the check box in front of the tree control node is selected, the following log displays the data of the selected node
Tree component data loading will keep the state of each node inside, change the node selected state and click the refresh button, the component node state will remain unchanged, you can pass the parameter IsReset Force data reset

Reset
Keep
  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

Some nodes of the Tree can be set to disabled state

Demo

By setting the Disabled property of the data source TreeItem object, you can control whether this node can be checked or not. When set to false, it will not affect the node expansion. /shrink function

  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

For nodes of the same level, only one can be expanded at a time

Demo

Enable the accordion effect by setting the IsAccordion property of the Tree component

  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

Some nodes of Tree can be set to be expanded or selected by default

Demo

By setting the IsExpand property of the TreeItem object, you can control whether this node is in the expanded state by default. In this example, navigation 2 is in the expanded state by default, and the rest Node defaults to contracted state

  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

Control whether the component displays the icon by setting ShowIcon

Demo

By setting the ShowIcon property of the TreeItem object, you can control whether this node displays the icon or not

  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

By setting ClickToggleNode to control whether to expand and contract when the node is clicked

Demo

By setting the ClickToggleNode property of the TreeItem object, you can control whether this node can be expanded and contracted by clicking

  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

Tree can be enabled inside the component Checkbox will be displayed when it is built into the validation form DisplayName This function needs to be disabled in the tree component

Demo

Show Checkbox built into validation component ValidateForm by setting ShowCheckbox property does not show DisplayName

  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

Dynamically add child nodes when expanding a node

Demo

By setting the node HasChildNode to control whether to display the small arrow picture of the node. Add nodes through Tree's OnExpandNodeAsync delegate

  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • 懒加载延时

Implement your own node template by setting TreeItem Template

Demo
  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

Implement your own node style by setting TreeItem CssClass

Demo
  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

Get all nodes by setting the OnTreeItemChecked callback delegate

Demo
  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • Navigation three

By setting ShowSkeleton, the component displays the skeleton screen when the data is loaded asynchronously

Demo
  • navigation one
  • Navigation two
    • Sub menu 1
    • Sub menu 2
      • Sub Menu One
      • Sub Menu Two
        • Sub Menu Two sub menu one
          • Sub menu 1
          • Sub menu 2
          • Sub menu 3
        • Sub Menu Two sub menu two
        • Sub Menu Two sub menu three
      • Sub Menu Three
    • Sub menu 3
  • 延时加载

Attributes

Loading...

TreeItem property

Loading...
@page "/treeviews"
@inject IStringLocalizer<TreeViews> Localizer

<h3>Tree tree control</h3>
<h4>Present information in a clear hierarchy that can be expanded or collapsed</h4>

<Tips class="mt-3">
    <div><code>Tree</code> If the component is a generic component, you need to use <code>TItem</code> to specify the bound data model. In this example, the model is <code>TreeFoo</code> and needs to be set <code>TItem="TreeFoo"</code></div>
    <ul class="ul-demo mt-3">
        <li>Set <code>TreeItem</code> its <code>IsExpand</code> parameter to control whether the current child node is expanded</li>
        <li>When clicking on the small arrow to expand the child item, obtain the child item data collection through the <code>OnExpandNodeAsync</code> callback delegate method</li>
        <li>Keep the node state fallback mechanism, <code>ModelEqualityComparer</code> <code>CustomKeyAttribute</code> <code>IEqualityComparer<TItem></code> <code>Equals</code> overloaded method</li>
        <li>The component will remain in the <code>expanded</code> <code>collapsed</code> <code>selected</code> state</li>
        <li>Set whether the node is <b>expanded</b> state through <code>TreeItem<TItem>.IsExpand</code></li>
        <li>Set whether the node is <b>selected</b> state through <code>TreeItem<TItem>.IsActive</code></li>
        <li>Through <code>TreeItem<TItem>.Checked</code>, set whether the node is in <b>checked/single selection</b> state</li>
    </ul>
</Tips>

<p>Step 1: Set the <code>TItem</code> generic model</p>
<p>Step 2: Set <code>Items</code> to get the component data source <b>Note</b> The data source type is <code>IEnumerable<TreeItem<TItem>></code></p>
<p>Step 3: Set the <code>OnExpandNodeAsync</code> callback delegate to expand the response node to get the child data source collection</p>
<p>Step 4: Set <code>ModelEqualityComparer</code> to provide a component identification model comparison delegate method, <b>Note</b> This setting is optional. Perform downgrade search through the fallback mechanism explained above</p>

<DemoBlock Title="Basic usage" Introduction="Basic tree structure display" Name="Normal">
    <p>By setting the <code>OnTreeItemClick</code> property to monitor the event when the tree control node is clicked, the following log displays the data of the selected node when the tree control node is clicked</p>
    <TreeView TItem="TreeFoo" Items="@Items" OnTreeItemClick="@OnTreeItemClick" />
    <BlockLogger @ref="Trace" class="mt-3" />
</DemoBlock>

<DemoBlock Title="Checkbox" Introduction="Suitable for use when you need to select a level" Name="Checkbox">
    <p>
        <div>By setting the <code>OnTreeItemChecked</code> property to monitor the event when the tree control node is checked, when the check box in front of the tree control node is selected, the following log displays the data of the selected node</div>
        <div><code>Tree</code> component data loading will keep the state of each node inside, change the node selected state and click the <b>refresh</b> button, the component node state will remain unchanged, you can pass the parameter <code>IsReset</code> Force data reset</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="Whether to reset"></RadioList>
        </div>
        <div class="col-12 col-lg-auto">
            <Checkbox DisplayText="Automatically select child nodes" ShowAfterLabel="true" @bind-Value="@AutoCheckChildren" />
            <Checkbox DisplayText="Automatically select parent node" ShowAfterLabel="true" @bind-Value="@AutoCheckParent" class="ms-3" />
        </div>
        <div class="col-12 col-lg-auto">
            <Button Text="refresh" 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="Disabled state" Introduction="Some nodes of the Tree can be set to disabled state" Name="TreeDisable">
    <p>By setting the <code>Disabled</code> property of the data source <code>TreeItem</code> object, you can control whether this node can be checked or not. When set to <code>false</code>, it will not affect the node expansion. /shrink function</p>
    <TreeView TItem="TreeFoo" Items="@DisabledItems" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="Accordion mode" Introduction="For nodes of the same level, only one can be expanded at a time" Name="AccordionModel">
    <p>Enable the accordion effect by setting the <code>IsAccordion</code> property of the <code>Tree</code> component</p>
    <TreeView TItem="TreeFoo" Items="@GetAccordionItems()" OnExpandNodeAsync="OnExpandNodeAsync" ShowCheckbox="true" IsAccordion="true" />
</DemoBlock>

<DemoBlock Title="Expanded by default and selected by default" Introduction="Some nodes of <code>Tree</code> can be set to be expanded or selected by default" Name="DefauleExpand">
    <p>
        By setting the <code>IsExpand</code> property of the <code>TreeItem</code> object, you can control whether this node is in the expanded state by default. In this example, <b>navigation 2</b> is in the expanded state by default, and the rest Node defaults to contracted state
    </p>
    <TreeView TItem="TreeFoo" Items="@ExpandItems" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="Show icon" Introduction="Control whether the component displays the icon by setting <code>ShowIcon</code>" Name="TreeDisplayIcon">
    <p>
        By setting the <code>ShowIcon</code> property of the <code>TreeItem</code> object, you can control whether this node displays the icon or not
    </p>
    <TreeView TItem="TreeFoo" Items="@GetIconItems()" ShowIcon="true" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="Click on the node to expand and contract" Introduction="By setting <code>ClickToggleNode</code> to control whether to expand and contract when the node is clicked" Name="TreeClickExpand">
    <p>
        By setting the <code>ClickToggleNode</code> property of the <code>TreeItem</code> object, you can control whether this node can be expanded and contracted by clicking
    </p>
    <TreeView TItem="TreeFoo" Items="@Items" ShowIcon="true" ShowCheckbox="true" ClickToggleNode="true" />
</DemoBlock>

<DemoBlock Title="The Tree component is built into the validation form" Introduction="<code>Tree</code> can be enabled inside the component <code>Checkbox</code> will be displayed when it is built into the validation form <code>DisplayName</code> This function needs to be disabled in the tree component" Name="TreeValidationForm">
    <p>Show <code>Checkbox</code> built into validation component <code>ValidateForm</code> by setting <code>ShowCheckbox</code> property does not show <code>DisplayName</code></p>
    <ValidateForm Model="@Model">
        <TreeView TItem="TreeFoo" Items="@Items" OnTreeItemClick="@OnTreeItemClick" ShowCheckbox="true" />
    </ValidateForm>
</DemoBlock>

<DemoBlock Title="Lazy loading" Introduction="Dynamically add child nodes when expanding a node" Name="TreeLazyLoading">
    <p>
        By setting the node <code>HasChildNode</code> to control whether to display the small arrow picture of the node. Add nodes through Tree's <code>OnExpandNodeAsync</code> delegate
    </p>
    <TreeView TItem="TreeFoo" ClickToggleNode="true" Items="@GetLazyItems()" OnExpandNodeAsync="OnExpandNodeAsync" />
</DemoBlock>

<DemoBlock Title="Custom node" Introduction="Implement your own node template by setting <code>TreeItem</code> <code>Template</code>" Name="TreeCustomNode">
    <TreeView TItem="TreeFoo" ClickToggleNode="true" Items="GetTemplateItems()" />
</DemoBlock>

<DemoBlock Title="Node color" Introduction="Implement your own node style by setting <code>TreeItem</code> <code>CssClass</code>" Name="TreeNodeColor">
    <TreeView TItem="TreeFoo" ClickToggleNode="true" Items="GetColorItems()" />
</DemoBlock>

<DemoBlock Title="Get all selected nodes" Introduction="Get all nodes by setting the <code>OnTreeItemChecked</code> callback delegate" Name="CheckedItems">
    <TreeView TItem="TreeFoo" ShowCheckbox="true" Items="@Items" OnTreeItemChecked="@OnTreeItemChecked" />
    <BlockLogger @ref="TraceCheckedItems" class="mt-3" />
</DemoBlock>

<DemoBlock Title="Loading skeleton screen" Introduction="By setting <code>ShowSkeleton</code>, the component displays the skeleton screen when the data is loaded asynchronously" Name="ShowSkeleton">
    <Button Text="Asynchronous loading" 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 property" />
// 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 Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Web;

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>? LocalizerFoo { get; set; }

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

    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", "Reset"),
        new("False", "Keep")
    };

    /// <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[]
    {
        new AttributeItem() {
            Name = "Items",
            Description = "menu data set",
            Type = "IEnumerable<TreeItem>",
            ValueList = " — ",
            DefaultValue = "new List<TreeItem>(20)"
        },
        new AttributeItem() {
            Name = "ClickToggleNode",
            Description = "Whether to expand or contract children when a node is clicked",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowCheckbox",
            Description = "Whether to display CheckBox",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowIcon",
            Description = "Whether to display Icon",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowSkeleton",
            Description = "Whether to display the loading skeleton screen",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = nameof(TreeView<string>.OnTreeItemClick),
            Description = "Callback delegate when tree control node is clicked",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeView<string>.OnTreeItemChecked),
            Description = "Callback delegate when tree control node is selected",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeView<string>.OnExpandNodeAsync),
            Description = "Tree control node expand callback delegate",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        }
    };

    private static IEnumerable<AttributeItem> GetTreeItemAttributes() => new AttributeItem[]
    {
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.Items),
            Description = "Child node data source",
            Type = "List<TreeItem<TItem>>",
            ValueList = " — ",
            DefaultValue = "new ()"
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.Text),
            Description = "Display text",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.Icon),
            Description = "Show icon",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.CssClass),
            Description = "Node custom style",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.CheckedState),
            Description = "Is selected",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.IsDisabled),
            Description = "Is disabled",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.IsExpand),
            Description = "Whether to expand",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "true"
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.HasChildren),
            Description = "Whether there are child nodes",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem() {
            Name = nameof(TreeViewItem<TreeFoo>.ShowLoading),
            Description = "Whether to show child node loading animation",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem()
        {
            Name = nameof(TreeViewItem<TreeFoo>.Template),
            Description = "Child node template",
            Type = nameof(RenderFragment),
            ValueList = " — ",
            DefaultValue = " — "
        }
    };
}

B station related video link

No

交流群

QQ Group:BootstrapAdmin & Blazor 795206915 675147445 Welcome to join the group discussion
img
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 Component library updated to 7.2.5-beta02

Bootstrap Blazor at present has more than 120 components. This component is based on Bootstrap Blazor An enterprise-level component library that provides several types of common components such as layout, navigation, form, data, notification, icon, voice, etc. Each component has been carefully designed with modularity, responsiveness and excellent performance. Starting from more practical scenarios, meeting the needs of various scenarios, greatly reducing the time cost of developers, greatly shortening the development cycle, greatly improving development efficiency, and providing a set of General Rights Management System Example project。Bootstrap Blazor Products are maintained by a professional full-time technical team, with efficient response speed, diversified solutions, long-term support, and enterprise-level support. At present, it has been used in many well-known state-owned enterprises, and the project is running stably with a maximum of 1200 people online. On the right is the QR code of the Chinese Blazor QQ community with the largest number of people in China, welcome to scan and join the group.

component updated to 6.6.0 Change log [portal] If the component brings you convenience, please help to light up the project Star github gitee

QQGroup
QQ 795206915