1. 程式人生 > 其它 >BootstrapBlazor實戰-Tree樹形控制元件使用(1)

BootstrapBlazor實戰-Tree樹形控制元件使用(1)

實戰BootstrapBlazor樹型控制元件Tree的使用, 以及整合Freesql orm快速製作資料庫後臺維護頁面

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

1.Tree 樹形控制元件

用清晰的層級結構展示資訊,可展開或摺疊

基礎用法

基礎的樹形結構展示

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

多選框

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

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

單選框

適用於單選節點

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

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

  • 禁用狀態:可將 Tree 的某些節點設定為禁用狀態
  • 手風琴模式:對於同一級的節點,每次只能展開一個
  • 預設展開和預設選中:可將 Tree 的某些節點設定為預設展開或預設選中

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

  • 節點顏色
  • 懶載入

  • 獲取所有選中節點

等等....

在這裡篇幅有限不一一介紹,更多使用說明參考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