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

Table 表格

常用于大数据单表维护

通过设置表格的 IsExcel 属性,使组件呈现为类似 Excel

Demo

Excel 模式下绑定是 动态类型 时,无法使用 TableColumn 对列属性进行设置,本例中使用 DynamicContext 实例对象 DataTableDynamicContext 构造函数进行设置

Loading...

设置列 Items 值,将枚举类型渲染成 Select 组件

Demo
DataTableDynamicContext = new(UserData, (context, col) =>
{
    if (col.GetFieldName() == nameof(Foo.Education))
    {
        col.ComponentType = typeof(Select<string>);
        col.Items = typeof(EnumEducation).ToSelectList(new SelectedItem("", "未设置"));
    }
});
通过上面代码将 Education 列使用 Select 组件渲染

本示例用于测试 Excel 模式下键盘支持

Demo

目前支持 Tab

Loading...

使用 DatTable 为数据源时,需要按照下面的步骤进行设置

1. 设置数据源上下文
设置 Table 组件的 TItem 属性值为 DynamicObject
设置 Table 组件的 DynamicContext 属性值为 DataTableDynamicContext 实例

protected override void OnInitialized()
{
    base.OnInitialized();

    DataTableDynamicContext = new(UserData, (context, col) =>
    {
        // 设置 Enum 类型渲染成 Select
        if (col.GetFieldName() == nameof(Foo.Education))
        {
            col.ComponentType = typeof(Select<string>);

            // 将枚举转化为 List
            col.Items = typeof(EnumEducation).ToSelectList(new SelectedItem("", Localizer["NullItemText"].Value));
        }
    });
}

2. 处理 DataRow 变化逻辑
设置 OnChanged 回调委托函数处理 新建/删除 逻辑

protected override void OnInitialized()
{
    DataTableDynamicContext.OnChanged = args =>
    {
        // 输出日志信息
        Trace.Log($"集合值变化通知 行: {args.Items.Count()} - 类型: {args.ChangedType}");
        return Task.CompletedTask;
    };
}

3. 处理 DataCell 变化逻辑
设置 OnValueChanged 回调委托函数处理单元格 更新 逻辑

protected override void OnInitialized()
{
    // 获得内置 OnValueChanged 回调
    var method = DataTableDynamicContext.OnValueChanged;

    DataTableDynamicContext.OnValueChanged = async (model, col, val) =>
    {
        // 调用内部提供的方法
        if (method != null)
        {
            // 内部方法会更新原始数据源 DataTable
            await method(model, col, val);
        }

        // 输出日志信息
        Trace.Log($"单元格变化通知 列: {col.GetFieldName()} - 值: {val?.ToString()}");
    };
}
@page "/tables/dynamicexcel"

<h3>Table 表格</h3>

<h4>常用于大数据单表维护</h4>

<DemoBlock Title="Excel 模式" Introduction="通过设置表格的 <code>IsExcel</code> 属性,使组件呈现为类似 <code>Excel</code>" Name="Excel">
    <p><code>Excel</code> 模式下绑定是 <b>动态类型</b> 时,无法使用 <code>TableColumn</code> 对列属性进行设置,本例中使用 <code>DynamicContext</code> 实例对象 <code>DataTableDynamicContext</code> 构造函数进行设置</p>
    <Table TItem="DynamicObject" DynamicContext="DataTableDynamicContext"
           IsBordered="true" IsMultipleSelect="true" IsExcel="true">
    </Table>
    <BlockLogger @ref="Trace" class="mt-3" />
</DemoBlock>

<DemoBlock Title="枚举类型" Introduction="设置列 <code>Items</code> 值,将枚举类型渲染成 <code>Select</code> 组件" Name="Enum">
    <Pre>DataTableDynamicContext = new(UserData, (context, col) =>
{
    if (col.GetFieldName() == nameof(Foo.Education))
    {
        col.ComponentType = typeof(Select<string>);
        col.Items = typeof(EnumEducation).ToSelectList(new SelectedItem("", "未设置"));
    }
});</Pre>
    <div>
        通过上面代码将 <code>Education</code> 列使用 <code>Select</code> 组件渲染
    </div>
</DemoBlock>

<DemoBlock Title="键盘支持" Introduction="本示例用于测试 <code>Excel</code> 模式下键盘支持" Name="Keyboard">
    <p>目前支持 <kbd><i class="fa fa-arrow-up"></i></kbd> <kbd><i class="fa fa-arrow-down"></i></kbd> <kbd><i class="fa fa-arrow-left"></i></kbd> <kbd><i class="fa fa-arrow-right"></i></kbd> <kbd>Tab</kbd></p>
    <Table TItem="DynamicObject" DynamicContext="DataTableKeyboardDynamicContext"
           IsBordered="true" IsMultipleSelect="true" IsExcel="true">
    </Table>
</DemoBlock>

<Tips class="mt-3">
    <p>开启 <code>IsExcel</code> 模式后,部分参数将不再生效,斑马线 <code>IsStriped</code> 树形表格 <code>IsTree</code> 明细行 <code>IsDetails</code> 多选栏 <code>IsMultipleSelect</code></p>
</Tips>

<p class="mt-3">使用 <code>DatTable</code> 为数据源时,需要按照下面的步骤进行设置</p>

<p>
    <div class="code-label">1. 设置数据源上下文</div>
    <div class="mt-2">设置 <code>Table</code> 组件的 <code>TItem</code> 属性值为 <code>DynamicObject</code></div>
    <div class="mt-2">设置 <code>Table</code> 组件的 <code>DynamicContext</code> 属性值为 <code>DataTableDynamicContext</code> 实例</div>
</p>

<Pre>protected override void OnInitialized()
{
    base.OnInitialized();

    DataTableDynamicContext = new(UserData, (context, col) =>
    {
        // 设置 Enum 类型渲染成 Select
        if (col.GetFieldName() == nameof(Foo.Education))
        {
            col.ComponentType = typeof(Select<string>);

            // 将枚举转化为 List
            col.Items = typeof(EnumEducation).ToSelectList(new SelectedItem("", Localizer["NullItemText"].Value));
        }
    });
}</Pre>

<p>
    <div class="code-label">2. 处理 <code>DataRow</code> 变化逻辑</div>
    <div class="mt-2">设置 <code>OnChanged</code> 回调委托函数处理 <b>新建/删除</b> 逻辑</div>
</p>

<Pre>protected override void OnInitialized()
{
    DataTableDynamicContext.OnChanged = args =>
    {
        // 输出日志信息
        Trace.Log($"集合值变化通知 行: {args.Items.Count()} - 类型: {args.ChangedType}");
        return Task.CompletedTask;
    };
}</Pre>

<p>
    <div class="code-label">3. 处理 <code>DataCell</code> 变化逻辑</div>
    <div class="mt-2">设置 <code>OnValueChanged</code> 回调委托函数处理单元格 <b>更新</b> 逻辑</div>
</p>

<Pre>protected override void OnInitialized()
{
    // 获得内置 OnValueChanged 回调
    var method = DataTableDynamicContext.OnValueChanged;

    DataTableDynamicContext.OnValueChanged = async (model, col, val) =>
    {
        // 调用内部提供的方法
        if (method != null)
        {
            // 内部方法会更新原始数据源 DataTable
            await method(model, col, val);
        }

        // 输出日志信息
        Trace.Log($"单元格变化通知 列: {col.GetFieldName()} - 值: {val?.ToString()}");
    };
}</Pre>
// 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.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using System.Data;

namespace BootstrapBlazor.Shared.Samples.Table;

/// <summary>
/// 
/// </summary>
partial class TablesDynamicExcel
{
    [NotNull]
    private DataTableDynamicContext? DataTableDynamicContext { get; set; }

    [NotNull]
    private DataTableDynamicContext? DataTableKeyboardDynamicContext { get; set; }

    private DataTable UserData { get; } = new DataTable();

    private DataTable KeyboardData { get; } = new DataTable();

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

    [Inject]
    [NotNull]
    private IStringLocalizer<Tables>? TablesLocalizer { get; set; }

    private string? ButtonAddColumnText { get; set; }

    private string? ButtonRemoveColumnText { get; set; }

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

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

        ButtonAddColumnText ??= TablesLocalizer[nameof(ButtonAddColumnText)];
        ButtonRemoveColumnText ??= TablesLocalizer[nameof(ButtonRemoveColumnText)];

        // 初始化 DataTable
        InitDataTable();

        // 初始化 DataTableContext 绑定 Table 组件
        InitDataTableContext();

        // 键盘支持示例
        InitDataTableKeyboard();
    }

    private void InitDataTable()
    {
        UserData.Columns.Add(new DataColumn(nameof(Foo.DateTime), typeof(DateTime)) { DefaultValue = DateTime.Now });
        UserData.Columns.Add(nameof(Foo.Name), typeof(string));
        UserData.Columns.Add(nameof(Foo.Complete), typeof(bool));
        UserData.Columns.Add(nameof(Foo.Education), typeof(string));
        UserData.Columns.Add(nameof(Foo.Count), typeof(int));

        Foo.GenerateFoo(Localizer, 10).ForEach(f =>
        {
            UserData.Rows.Add(f.DateTime, f.Name, f.Complete, f.Education, f.Count);
        });
    }

    private void InitDataTableContext()
    {
        DataTableDynamicContext = new(UserData, (context, col) =>
        {
            // 设置 Enum 类型渲染成 Select
            if (col.GetFieldName() == nameof(Foo.Education))
            {
                col.ComponentType = typeof(Select<string>);
                col.Items = typeof(EnumEducation).ToSelectList(new SelectedItem("", Localizer["NullItemText"].Value));
            }
        });

        var method = DataTableDynamicContext.OnValueChanged;
        DataTableDynamicContext.OnValueChanged = async (model, col, val) =>
        {
            // 调用内部提供的方法
            if (method != null)
            {
                // 内部方法会更新原始数据源 DataTable
                await method(model, col, val);
            }

            // 输出日志信息
            Trace.Log($"单元格变化通知 列: {col.GetFieldName()} - 值: {val?.ToString()}");
        };
        DataTableDynamicContext.OnChanged = args =>
        {
            // 输出日志信息
            Trace.Log($"集合值变化通知 行: {args.Items.Count()} - 类型: {args.ChangedType}");
            return Task.CompletedTask;
        };
    }

    private void InitDataTableKeyboard()
    {
        KeyboardData.Columns.Add("Column 1", typeof(string));
        KeyboardData.Columns.Add("Column 2", typeof(string));
        KeyboardData.Columns.Add("Column 3", typeof(string));
        KeyboardData.Columns.Add("Column 4", typeof(string));
        KeyboardData.Columns.Add("Column 5", typeof(string));

        var index = 0;
        Foo.GenerateFoo(Localizer, 9).ForEach(f =>
        {
            index++;
            KeyboardData.Rows.Add($"Cell {index}1", $"Cell {index}2", $"Cell {index}3", $"Cell {index}4", $"Cell {index}5");
        });

        DataTableKeyboardDynamicContext = new(KeyboardData);
    }
}

B 站相关视频链接

交流群

QQ Group:BootstrapAdmin & Blazor 795206915 675147445 Welcome to join the group discussion
Themes
Bootstrap
Motronic
Ant Design (完善中)
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