Enterprise-level component library based on Bootstrap and Blazor

star nuget master download license repo commit

显示明细行功能

用于展示父子关系表数据

通过设置 DetailRowTemplate 模板设置明细行内容

Demo

明细行内显示绑定行的另外一个字段 学历 以普通文字形式呈现

Loading...

通过设置 DetailRowTemplate 模板设置明细行为子表数据

Demo

明细行内嵌套另外一个 Table 组件,由于每行都要关联子表数据,出于性能的考虑,此功能采用 懒加载 模式,即点击展开按钮后,再对嵌套 Table 进行数据填充,通过 ShowDetailRow 回调委托可以控制每一行是否显示明细行,本例中通过 Complete 属性来控制是否显示明细行,可通过翻页来测试本功能

Loading...

通过设置 Height 固定表头后模板设置明细行内容

Demo

本例中固定表头后,再开启明细行功能

Loading...

通过设置 DetailRowTemplate 模板设置明细行内容

Demo

本例中明细行内使用 Tab 组件再次将数据分割成两个 TabItem 内容,进行再次数据拆分演示

Loading...
@page "/tables/detail"

<h3>显示明细行功能</h3>

<h4>用于展示父子关系表数据</h4>

<Block Title="简单应用" Introduction="通过设置 <code>DetailRowTemplate</code> 模板设置明细行内容">
    <p>明细行内显示绑定行的另外一个字段 <code>学历</code> 以普通文字形式呈现</p>
    <Tips>
        <p>通过 <code>IsDetails</code> 参数可以实现动态切换是否显示明细行功能</p>
    </Tips>
    <Table TItem="Foo"
           IsPagination="true" PageItemsSource="@PageItemsSource"
           IsStriped="true" IsBordered="true" IsDetails="@IsDetails"
           ShowToolbar="true" ShowDefaultButtons="false"
           OnQueryAsync="@OnQueryAsync">
        <TableColumns>
            <TableColumn @bind-Field="@context.DateTime" Width="180" />
            <TableColumn @bind-Field="@context.Name" Width="100" />
            <TableColumn @bind-Field="@context.Address" />
            <TableColumn @bind-Field="@context.Count" />
        </TableColumns>
        <DetailRowTemplate>
            <div>学历: @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
        </DetailRowTemplate>
    </Table>

    <Button Text="@DetailText" OnClick="OnClickDetailRow" class="mt-3"></Button>
</Block>

<Block Title="嵌套 Table 组件应用" Introduction="通过设置 <code>DetailRowTemplate</code> 模板设置明细行为子表数据">
    <p>明细行内嵌套另外一个 <code>Table</code> 组件,由于每行都要关联子表数据,出于性能的考虑,此功能采用 <code>懒加载</code> 模式,即点击展开按钮后,再对嵌套 <code>Table</code> 进行数据填充,通过 <code>ShowDetailRow</code> 回调委托可以控制每一行是否显示明细行,本例中通过 <code>Complete</code> 属性来控制是否显示明细行,可通过翻页来测试本功能</p>
    <Table TItem="Foo"
           IsPagination="true" PageItemsSource="@PageItemsSource"
           IsStriped="true" IsBordered="true"
           ShowToolbar="true" ShowDefaultButtons="false"
           OnQueryAsync="@OnQueryAsync" ShowDetailRow="ShowDetailRow">
        <TableColumns>
            <TableColumn @bind-Field="@context.DateTime" Width="180" />
            <TableColumn @bind-Field="@context.Name" Width="100" />
            <TableColumn @bind-Field="@context.Address" />
            <TableColumn @bind-Field="@context.Count" />
        </TableColumns>
        <DetailRowTemplate>
            @{
                // 此段代码为提高性能
                var cacheKey = context.Name ?? "";
                var DetailDataSource = Enumerable.Empty<DetailRow>();
                if (Cache.ContainsKey(cacheKey))
                {
                    DetailDataSource = Cache[cacheKey];
                }
                else
                {
                    DetailDataSource = GetDetailRowsByName(cacheKey).ToList();
                    Cache.Add(cacheKey, DetailDataSource);
                }
            }
            <Table TItem="DetailRow" IsBordered="true" ShowToolbar="false" Items="@DetailDataSource">
                <TableColumns Context="Detail">
                    <TableColumn @bind-Field="@Detail.Name" />
                    <TableColumn @bind-Field="@Detail.DateTime" Width="180" />
                    <TableColumn @bind-Field="@context.Complete" Width="70" />
                </TableColumns>
            </Table>
        </DetailRowTemplate>
    </Table>
</Block>

<Block Title="固定表头开启明细行功能" Introduction="通过设置 <code>Height</code> 固定表头后模板设置明细行内容">
    <p>本例中固定表头后,再开启明细行功能</p>
    <Table TItem="Foo" Height="200"
           IsStriped="true" IsBordered="true"
           ShowToolbar="true" ShowDefaultButtons="false"
           OnQueryAsync="@OnQueryAsync">
        <TableColumns>
            <TableColumn @bind-Field="@context.DateTime" Width="180" />
            <TableColumn @bind-Field="@context.Name" Width="100" />
            <TableColumn @bind-Field="@context.Address" />
            <TableColumn @bind-Field="@context.Count" />
        </TableColumns>
        <DetailRowTemplate>
            <div>学历: @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
        </DetailRowTemplate>
    </Table>
</Block>

<Block Title="明细行中使用 Tab 组件" Introduction="通过设置 <code>DetailRowTemplate</code> 模板设置明细行内容">
    <p>本例中明细行内使用 <code>Tab</code> 组件再次将数据分割成两个 <code>TabItem</code> 内容,进行再次数据拆分演示</p>
    <Table TItem="Foo" IsPagination="true" PageItemsSource="@PageItemsSource"
           IsStriped="true" IsBordered="true"
           ShowToolbar="true" ShowDefaultButtons="false"
           OnQueryAsync="@OnQueryAsync">
        <TableColumns>
            <TableColumn @bind-Field="@context.DateTime" Width="180" />
            <TableColumn @bind-Field="@context.Name" Width="100" />
            <TableColumn @bind-Field="@context.Address" />
            <TableColumn @bind-Field="@context.Count" />
        </TableColumns>
        <DetailRowTemplate>
            <Tab>
                <TabItem Text="明细数据">
                    @{
                        // 此段代码为提高性能
                        var cacheKey = context.Name ?? "";
                        var DetailDataSource = Enumerable.Empty<DetailRow>();
                        if (Cache.ContainsKey(cacheKey))
                        {
                            DetailDataSource = Cache[cacheKey];
                        }
                        else
                        {
                            DetailDataSource = GetDetailRowsByName(cacheKey).ToList();
                            Cache.Add(cacheKey, DetailDataSource);
                        }
                    }
                    <Table TItem="DetailRow" IsBordered="true" ShowToolbar="false" Items="@DetailDataSource" AutoGenerateColumns="true" />
                </TabItem>
                <TabItem Text="关联数据">
                    <div>学历: @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
                </TabItem>
            </Tab>
        </DetailRowTemplate>
    </Table>
</Block>
// 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.Pages.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;

namespace BootstrapBlazor.Shared.Pages.Table
{
    /// <summary>
    /// 
    /// </summary>
    public sealed partial class TablesDetailRow
    {
        private Dictionary<string, IEnumerable<DetailRow>> Cache { get; } = new();

        private static readonly Random random = new();

        private static IEnumerable<int> PageItemsSource => new int[] { 4, 10, 20 };

        [NotNull]
        private List<Foo>? Items { get; set; }

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

        [Inject]
        [NotNull]
        private IStringLocalizer<TablesDetailRow>? LocalizerDetailRow { get; set; }

        [NotNull]
        private string? DetailText { get; set; }

        /// <summary>
        /// OnInitialized 方法
        /// </summary>
        protected override void OnInitialized()
        {
            base.OnInitialized();

            DetailText ??= LocalizerDetailRow[$"{nameof(DetailText)}{!IsDetails}"];
            Items = Foo.GenerateFoo(Localizer);
        }

        private static IEnumerable<DetailRow> GetDetailRowsByName(string name) => Enumerable.Range(1, 4).Select(i => new DetailRow()
        {
            Id = i,
            Name = name,
            DateTime = DateTime.Now.AddDays(i - 1),
            Complete = random.Next(1, 100) > 50
        });

        private Task<QueryData<Foo>> OnQueryAsync(QueryPageOptions options)
        {
            IEnumerable<Foo> items = Items;

            // 设置记录总数
            var total = items.Count();

            // 内存分页
            items = items.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems).ToList();

            return Task.FromResult(new QueryData<Foo>()
            {
                Items = items,
                TotalCount = total
            });
        }

        private bool IsDetails { get; set; } = true;

        private void OnClickDetailRow()
        {
            DetailText = LocalizerDetailRow[$"{nameof(DetailText)}{IsDetails}"];
            IsDetails = !IsDetails;
        }

        private class DetailRow
        {
            /// <summary>
            /// 
            /// </summary>
            [DisplayName("主键")]
            public int Id { get; set; }

            /// <summary>
            /// 
            /// </summary>
            [DisplayName("培训课程")]
            [AutoGenerateColumn(Order = 10)]
            public string Name { get; set; } = "";

            /// <summary>
            /// 
            /// </summary>
            [DisplayName("日期")]
            [AutoGenerateColumn(Order = 20, Width = 180)]
            public DateTime DateTime { get; set; }

            /// <summary>
            /// 
            /// </summary>
            [DisplayName("是/否")]
            [AutoGenerateColumn(Order = 30, Width = 70)]
            public bool Complete { get; set; }
        }

        private static bool ShowDetailRow(Foo item) => item.Complete;
    }
}

B 站相关视频链接

[传送门]

交流群

QQ Group:BootstrapAdmin & Blazor 795206915( Full) 675147445 Welcome to join the group discussion
Themes
Bootstrap
Ant Design (完善中)
Bluma (完善中)
LayUI (完善中)
Motronic (已集成)
An error has occurred. This application may no longer respond until reloaded. Reload