Enterprise-level component library based on Bootstrap and Blazor

star nuget license download repo commit master 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;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;

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