Bootstrap Blazor 實戰- Tree 樹形控件使用(1)


實戰BootstrapBlazor樹型控件Tree的使用, 以及整合Freesql orm快速制作數據庫后台維護頁面

動畫

BootstrapBlazor 是 Bootstrap 風格的 Blazor UI 組件庫 基於 Bootstrap 樣式庫精心打造,並且額外增加了 100 多種常用的組件,為您快速開發項目帶來非一般的感覺

demo演示的是Sqlite驅動,FreeSql支持多種數據庫,MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/達夢/神通/人大金倉/翰高/華為GaussDB/MsAccess

1.Tree 樹形控件

用清晰的層級結構展示信息,可展開或折疊

基礎用法

基礎的樹形結構展示

QQ截圖20220331232658

<Tree Items="@Items" OnTreeItemClick="@OnTreeItemClick" />

@code{
    private List<TreeItem> Items { get; set; } = TreeDataFoo.GetTreeItems(); //數據類在后面會有完整代碼

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

多選框

適用於需要選擇層級時使用

22222

<Tree Items="@CheckedItems" ShowCheckbox="true" OnTreeItemChecked="@OnTreeItemChecked" />

單選框

適用於單選節點

3333

<Tree Items="@CheckedItems" ShowRadio="true" />

除此之外還有很多屬性和用法,

  • 禁用狀態:可將 Tree 的某些節點設置為禁用狀態

image

  • 手風琴模式:對於同一級的節點,每次只能展開一個

image

  • 默認展開和默認選中:可將 Tree 的某些節點設置為默認展開或默認選中

  • 顯示圖標:通過設置 ShowIcon 來控制組件是否顯示圖標

image

  • 節點顏色

image

  • 懶加載

  • 獲取所有選中節點

等等....

在這里篇幅有限不一一介紹,更多使用說明參考https://www.blazor.zone/trees

2.新建工程 [步驟跟上篇:B03. BootstrapBlazor實戰 10分鍾編寫數據庫維護項目大同小異]

完整步驟

1.1 新建工程b05tree

dotnet new blazorserver -o b05tree

將項目添加到解決方案中:

dotnet sln add b05tree/b05tree.csproj

使用 nuget.org 進行 BootstrapBlazor 組件安裝, FreeSql sqlite庫,字體 ..

dotnet add b05tree package BootstrapBlazor
dotnet add b05tree package BootstrapBlazor.FontAwesome
dotnet add b05tree package FreeSql.Provider.Sqlite
dotnet add b05tree package Densen.FreeSql.Extensions.BootstrapBlazor

[可選]BootstrapBlazor官方BootstrapBlazor.DataAcces.FreeSql包替換Densen.FreeSql.Extensions.BootstrapBlazor

1.2 樣式表和Javascript 引用

增加主題樣式表到 Pages/_Layout.cshtml 文件中

刪除 <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />

並在下面添加兩行

<link href="_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css" rel="stylesheet">
<link href="_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css" rel="stylesheet">

添加 Javascript 引用到 Pages/_Layout.cshtml 文件中

<script src="_framework/blazor.server.js"></script> 之前添加

<script src="_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js" asp-append-version="true"></script>

1.3 添加增加命名空間引用到 _Imports.razor 文件中

@using BootstrapBlazor.Components

1.4 增加 BootstrapBlazorRoot 組件到 App.razor 文件中

<BootstrapBlazorRoot>
    <Router AppAssembly="@typeof(App).Assembly">
        ...
    </Router>
</BootstrapBlazorRoot>

1.5 添加BootstrapBlazor服務到 Program.cs 文件中

builder.Services.AddSingleton<WeatherForecastService>(); 后加入

builder.Services.AddBootstrapBlazor();

1.6 數據服務

添加FreeSql服務到 Program.cs
builder.Services.AddBootstrapBlazor(); 之前加入

builder.Services.AddFreeSql(option =>
{
    //demo演示的是Sqlite驅動,FreeSql支持多種數據庫,MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/達夢/神通/人大金倉/翰高/華為GaussDB/MsAccess
    option.UseConnectionString(FreeSql.DataType.Sqlite, "Data Source=test.db;")  //也可以寫到配置文件中
#if DEBUG
         //開發環境:自動同步實體
         .UseAutoSyncStructure(true)
         .UseNoneCommandParameter(true)
         //調試sql語句輸出
         .UseMonitorCommand(cmd => System.Console.WriteLine(cmd.CommandText))
#endif
    ;
});

[可選] Data Source寫到配置文件 appsettings.json :

  "ConnectionStrings": {
    "bb": "Data Source=test.db;"
  }

option.UseConnectionString(FreeSql.DataType.Sqlite, "Data Source=test.db;") 改為

option.UseConnectionString(FreeSql.DataType.Sqlite, builder.Configuration.GetConnectionString("bb"))

3. TreeItem數據實體類

新建目錄Model, 新建文件 Data/TreeDataFoo.cs

完整文件

using BootstrapBlazor.Components;

namespace b05tree;

class TreeDataFoo
{
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public static List<TreeItem> GetTreeItems0()
    {
        var items = new List<TreeItem>
        {
            new TreeItem() { Text = "001_系統管理", Id = "001" },
            new TreeItem() { Text = "001_01_基礎數據管理", Id = "001_01", ParentId = "001" },
            new TreeItem() { Text = "001_01_01_教師", Id = "001_01_01", ParentId = "001_01" },
            new TreeItem() { Text = "001_01_02_職工", Id = "001_01_02", ParentId = "001_01" },

            new TreeItem() { Text = "001_02_餐廳數據管理", Id = "001_02", ParentId = "001" },
            new TreeItem() { Text = "001_02_01_廚師", Id = "001_02_01", ParentId = "001_02" },
            new TreeItem() { Text = "001_02_02_服務員", Id = "001_02_02", ParentId = "001_02" },

        }; 
        // 算法獲取屬性結構數據
        return items.CascadingTree().ToList();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public static List<TreeItem> GetTreeItems(int count=30)
    {
        var items = new List<TreeItem>
        {
            new TreeItem() { Text = "系統管理", Id = "1010" },
            new TreeItem() { Text = "基礎數據管理", Id = "1040", ParentId = "1010" },
            new TreeItem() { Text = "基礎管理", Id = "1070", ParentId = "1040" },
            new TreeItem() { Text = "基礎2管理", Id = "1080", ParentId = "1040" },
            new TreeItem() { Text = "基礎3管理", Id = "1090", ParentId = "1040" },
            new TreeItem() { Text = "基礎4管理", Id = "1100", ParentId = "1040" },

            new TreeItem() { Text = "系統管理2", Id = "1011" },
            new TreeItem() { Text = "基礎數據管理2", Id = "1210", ParentId = "1011" },


            new TreeItem() { Text = "系統管理3", Id = "1012" }, //_懶加載演示

            new TreeItem() { Text = "系統管理4", Id = "1014" },//_懶加載延時演示 

        };

        var items1000 = new List<TreeItem>();
        for (int i = 0; i < count; i++)
        {
            items1000.Add(new TreeItem() { Text = $"教師{-i}信息", Id = $"112{i}0", ParentId = "1070", IsActive = true });
        }
        for (int i = 0; i < count; i++)
        {
            items1000.Add(new TreeItem() { Text = $"教師基礎2-{i}信息", Id = $"113{i}0", ParentId = "1080", IsActive = true });
        }
        for (int i = 0; i < count; i++)
        {
            items1000.Add(new TreeItem() { Text = $"教師基礎3-{i}信息", Id = $"114{i}0", ParentId = "1090", IsActive = true });
        }
        for (int i = 0; i < count; i++)
        {
            items1000.Add(new TreeItem() { Text = $"教師基礎4-{i}信息", Id = $"115{i}0", ParentId = "1100", IsActive = true });
        }

        for (int i = 0; i < count; i++)
        {
            items1000.Add(new TreeItem() { Text = $"教師II{-i}信息", Id = $"116{i}0", ParentId = "1210", IsActive = true });
        }

        items.AddRange(items1000);
        // 算法獲取屬性結構數據
        return items.CascadingTree().ToList();
    }
}

4. 界面和代碼

添加代碼到 Pages/Index.razor 文件中

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

<p>
    簡單用法
</p>

<Tree ClickToggleNode="true" Items="@TreeDataFoo.GetTreeItems0()" />

<br/>
<br/>
<br/>
<br/>

<p>
    通過設置節點 <code>HasChildNode</code> 控制是否顯示節點小箭頭圖片 。通過Tree的 <code>OnExpandNode</code> 委托添加節點 。通過Tree的 <code>Key</code> 委托添加節點
</p>
<Tree ClickToggleNode="true" Items="@GetLazyItems()" ShowCheckbox="true" OnTreeItemChecked="@OnTreeItemChecked" OnExpandNode="OnExpandNode" />

添加Index.razor.cs代碼后置c#文件

using BootstrapBlazor.Components;

namespace b05tree.Pages;

/// <summary>
/// 
/// </summary>
public sealed partial class Index
{

    private static List<TreeItem> GetLazyItems()
    {
        var ret = TreeDataFoo.GetTreeItems();

        ret[0].Items[0].Items[2].Text += "_默認打開";
        ret[0].Items[0].Items[2].IsCollapsed = false;

        ret[2].Text += "_懶加載";
        ret[2].HasChildNode = true;

        ret[3].Text += "_懶加載延時";
        ret[3].HasChildNode = true;
        ret[3].Key = "Delay";

        for (int i = 0; i < ret[0].Items[0].Items[0].Items.Count; i++)
        {
            ret[0].Items[0].Items[0].Items[i].Checked = true;
            ret[0].Items[0].Items[1].Items[i].Checked = true;
            ret[0].Items[0].Items[2].Items[i].Checked = true;
        }
        return ret;
    }



    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",
                        HasChildNode = true,
                        Key = "Delay"
                    },
                    new TreeItem() { Text = "懶加載子節點3" }
            });
            item.ShowLoading = false;
        }
    }

    private Task OnTreeItemChecked(List<TreeItem> items)
    {
        //TraceCheckedItems.Log($"當前共選中{items.Count}項");
        return Task.CompletedTask;
    }

}

5. 運行

演示項目為普通式樣,可選框式樣,懶加載子節點式樣,懶加載+延時(模擬后台數據加載) 

更多使用說明參考<https://www.blazor.zone/trees>

大佬和同學們有問題在文章后面留言,我都會一一盡力解答. 下一篇介紹整合Freesql orm快速制作數據庫后台維護頁面

項目源碼

Github | Gitee

關聯項目

FreeSql QQ群:4336577(已滿)、8578575(已滿)、52508226(在線)

BA & Blazor QQ群:795206915、675147445

知識共享許可協議

本作品采用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名AlexChow(包含鏈接: https://github.com/densen2014 ),不得用於商業目的,基於本文修改后的作品務必以相同的許可發布。如有任何疑問,請與我聯系

AlexChow

今日頭條 | 博客園 | 知乎 | Gitee | GitHub


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM