doc: update the table component detailrow demos (#483)

Co-authored-by: Argo Zhang <argo@live.ca>
This commit is contained in:
Lambert Lee 2023-02-04 20:30:01 +08:00 committed by GitHub
parent ba880397df
commit 936b4a7fea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 443 additions and 252 deletions

View File

@ -0,0 +1,33 @@
@inject MockDataTableDynamicService DataTableDynamicService
<div>
<Table TItem="DynamicObject" DynamicContext="DataTableDynamicContext"
IsStriped="true" IsBordered="true" IsExcel="true"
ShowToolbar="true" ShowDefaultButtons="false">
<DetailRowTemplate>
@{
var detailContext = GetDetailDataTableDynamicContext(context);
}
<div class="p-2 w-100">
<Table TItem="DynamicObject" DynamicContext="detailContext" IsStriped="true" IsBordered="true" IsExcel="true">
</Table>
</div>
</DetailRowTemplate>
</Table>
</div>
@code {
private DataTableDynamicContext? DataTableDynamicContext { get; set; }
/// <summary>
/// OnInitialized 方法
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
DataTableDynamicContext = DataTableDynamicService.CreateContext();
}
private DynamicObjectContext GetDetailDataTableDynamicContext(DynamicObject context) => DataTableDynamicService.CreateDetailContext(context);
}

View File

@ -0,0 +1,70 @@
@using System.ComponentModel;
@inject IStringLocalizer<TablesDetailRowHeight> Localizer
@inject IStringLocalizer<Foo> FooLocalizer
<div>
<Table TItem="Foo" Height="400" IsFixedHeader="true"
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>@Localizer["EducationText"] @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
</DetailRowTemplate>
</Table>
</div>
@code {
[NotNull]
private List<Foo>? Items { get; set; }
/// <summary>
/// OnInitialized 方法
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
Items = Foo.GenerateFoo(FooLocalizer);
}
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 class DetailRow
{
[DisplayName("主键")]
public int Id { get; set; }
[DisplayName("培训课程")]
[AutoGenerateColumn(Order = 10)]
public string Name { get; set; } = "";
[DisplayName("日期")]
[AutoGenerateColumn(Order = 20, Width = 180)]
public DateTime DateTime { get; set; }
[DisplayName("是/否")]
[AutoGenerateColumn(Order = 30, Width = 70)]
public bool Complete { get; set; }
}
}

View File

@ -0,0 +1,84 @@
@inject IStringLocalizer<TablesDetailRowIsDetails> Localizer
@inject IStringLocalizer<Foo> FooLocalizer
<div>
<Table TItem="Foo" @ref="@Table"
IsPagination="true" PageItemsSource="@PageItemsSource"
IsStriped="true" IsBordered="true" IsDetails="IsDetails"
ShowToolbar="true" ShowDefaultButtons="false" ShowRefresh="false" OnDoubleClickRowCallback="OnDoubleClickRowCallback()!"
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>@Localizer["EducationText"] @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
</DetailRowTemplate>
</Table>
<Button Text="@DetailText" OnClick="OnClickDetailRow" class="mt-3"></Button>
</div>
@code {
private static IEnumerable<int> PageItemsSource => new int[] { 4, 10, 20 };
[NotNull]
private List<Foo>? Items { get; set; }
[NotNull]
private string? DetailText { get; set; }
[NotNull]
private Table<Foo>? Table { get; set; }
/// <summary>
/// OnInitialized 方法
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
Items = Foo.GenerateFoo(FooLocalizer);
}
private Func<Foo, Task>? OnDoubleClickRowCallback()
{
Func<Foo, Task>? ret = null;
if (IsDetails)
{
ret = foo =>
{
Table.ExpandDetailRow(foo);
return Task.CompletedTask;
};
}
return ret;
}
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 = Localizer[$"{nameof(DetailText)}{IsDetails}"];
IsDetails = !IsDetails;
}
}

View File

@ -0,0 +1,100 @@
@using System.ComponentModel;
@using System.Collections.Concurrent;
@inject IStringLocalizer<Foo> FooLocalizer
<div>
<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>
<Table TItem="DetailRow" IsBordered="true" ShowToolbar="false" Items="@GetDetailDataSource(context)">
<TableColumns Context="Detail">
<TableColumn @bind-Field="@Detail.Name" />
<TableColumn @bind-Field="@Detail.DateTime" Width="180" />
<TableColumn @bind-Field="@Detail.Complete" Width="70" />
</TableColumns>
</Table>
</DetailRowTemplate>
</Table>
</div>
@code {
private ConcurrentDictionary<string, List<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; }
/// <summary>
/// OnInitialized 方法
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
Items = Foo.GenerateFoo(FooLocalizer);
}
private static List<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
}).ToList();
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 List<DetailRow> GetDetailDataSource(Foo foo)
{
var cacheKey = foo.Name ?? "";
return Cache.GetOrAdd(cacheKey, key => GetDetailRowsByName(cacheKey));
}
private class DetailRow
{
[DisplayName("主键")]
public int Id { get; set; }
[DisplayName("培训课程")]
[AutoGenerateColumn(Order = 10)]
public string Name { get; set; } = "";
[DisplayName("日期")]
[AutoGenerateColumn(Order = 20, Width = 180)]
public DateTime DateTime { get; set; }
[DisplayName("是/否")]
[AutoGenerateColumn(Order = 30, Width = 70)]
public bool Complete { get; set; }
}
private static bool ShowDetailRow(Foo item) => item.Complete;
}

View File

@ -0,0 +1,101 @@
@using System.ComponentModel;
@using System.Collections.Concurrent;
@inject IStringLocalizer<TablesDetailRowTemplate> Localizer
@inject IStringLocalizer<Foo> FooLocalizer
<div>
<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="明细数据">
<Table TItem="DetailRow" IsBordered="true" ShowToolbar="false" Items="@GetDetailDataSource(context)" AutoGenerateColumns="true"></Table>
</TabItem>
<TabItem Text="@Localizer["TabItemText"]">
<div>@Localizer["EducationText"] @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
</TabItem>
</Tab>
</DetailRowTemplate>
</Table>
</div>
@code {
private ConcurrentDictionary<string, List<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; }
/// <summary>
/// OnInitialized 方法
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
Items = Foo.GenerateFoo(FooLocalizer);
}
private static List<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
}).ToList();
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 List<DetailRow> GetDetailDataSource(Foo foo)
{
var cacheKey = foo.Name ?? "";
return Cache.GetOrAdd(cacheKey, key => GetDetailRowsByName(cacheKey));
}
private class DetailRow
{
[DisplayName("主键")]
public int Id { get; set; }
[DisplayName("培训课程")]
[AutoGenerateColumn(Order = 10)]
public string Name { get; set; } = "";
[DisplayName("日期")]
[AutoGenerateColumn(Order = 20, Width = 180)]
public DateTime DateTime { get; set; }
[DisplayName("是/否")]
[AutoGenerateColumn(Order = 30, Width = 70)]
public bool Complete { get; set; }
}
}

View File

@ -4969,15 +4969,12 @@
"TF15": "Great-great-grandson menu three"
},
"BootstrapBlazor.Shared.Samples.Table.TablesDetailRow": {
"DetailTextTrue": "Enable",
"DetailTextFalse": "Disable",
"Title": "Display detail line function",
"Desc": "Used to display parent-child relationship table data",
"TablesDetailRowTitle": "Display detail line function",
"TablesDetailRowDesc": "Used to display parent-child relationship table data",
"DetailRowTemplateTitle": "Simple Application",
"DetailRowTemplateIntro": "Set the detail row content by setting the <code>DetailRowTemplate</code> template",
"DetailRowTemplateP": "In the detail row, another field <code>education</code> of the binding row is displayed in the form of ordinary text",
"DetailRowTemplateP1": "Through the <code>IsDetails</code> parameter, it is possible to dynamically switch whether to display the detail row function",
"EducationText": "Education:",
"DetailRowTemplate2Title": "Nested Table Component Application",
"DetailRowTemplate2Intro": "Set the detail behavior sub-table data by setting the <code>DetailRowTemplate</code> template",
"DetailRowTemplate2P": "Another <code>Table</code> component is nested in the detail row. Since each row must be associated with sub-table data, for performance reasons, this function adopts the <code>lazy loading</code> mode. , that is, after clicking the expand button, the nested <code>Table</code> is filled with data, and the <code>ShowDetailRow</code> callback delegate can control whether each row displays the detail row. In this example, the <code> Complete</code> attribute to control whether to display the detail line, you can test this function by turning the page",
@ -4987,10 +4984,21 @@
"DetailRowTemplate3Title": "Use Tab component in detail row",
"DetailRowTemplate3Intro": "Set the detail row content by setting the <code>DetailRowTemplate</code> template",
"DetailRowTemplate3P": "In this example, the <code>Tab</code> component is used in the detail row to split the data into two <code>TabItem</code> contents again to demonstrate the data splitting again",
"TabItemText": "Associated Data",
"DynamicTitle": "Detail row of dynamic data",
"DynamicIntro": "Data source is <code>DataTable</code>"
},
"BootstrapBlazor.Shared.Demos.Table.TablesDetailRow.TablesDetailRowIsDetails": {
"EducationText": "Education:",
"DetailTextTrue": "Enable",
"DetailTextFalse": "Disable"
},
"BootstrapBlazor.Shared.Demos.Table.TablesDetailRow.TablesDetailRowHeight": {
"EducationText": "Education:"
},
"BootstrapBlazor.Shared.Demos.Table.TablesDetailRow.TablesDetailRowTemplate": {
"TabItemText": "Associated Data",
"EducationText": "Education:"
},
"BootstrapBlazor.Shared.Samples.Table.Tables": {
"ButtonAddColumnText": "Add Column",
"ButtonRemoveColumnText": "Remove Column",

View File

@ -5003,15 +5003,12 @@
"TablesFooterTemplateTotal": "合计:"
},
"BootstrapBlazor.Shared.Samples.Table.TablesDetailRow": {
"DetailTextTrue": "关闭明细行",
"DetailTextFalse": "开启明细行",
"Title": "显示明细行功能",
"Desc": "用于展示父子关系表数据",
"TablesDetailRowTitle": "显示明细行功能",
"TablesDetailRowDesc": "用于展示父子关系表数据",
"DetailRowTemplateTitle": "简单应用",
"DetailRowTemplateIntro": "通过设置 <code>DetailRowTemplate</code> 模板设置明细行内容",
"DetailRowTemplateP": "明细行内显示绑定行的另外一个字段 <code>学历</code> 以普通文字形式呈现。支持双击展开明细行的功能,双击回调仅 <b>PC</b> 端支持,请在<b>PC</b> 端测试。",
"DetailRowTemplateP1": "通过 <code>IsDetails</code> 参数可以实现动态切换是否显示明细行功能",
"EducationText": "学历:",
"DetailRowTemplate2Title": "嵌套 Table 组件应用",
"DetailRowTemplate2Intro": "通过设置 <code>DetailRowTemplate</code> 模板设置明细行为子表数据",
"DetailRowTemplate2P": "明细行内嵌套另外一个 <code>Table</code> 组件,由于每行都要关联子表数据,出于性能的考虑,此功能采用 <code>懒加载</code> 模式,即点击展开按钮后,再对嵌套 <code>Table</code> 进行数据填充,通过 <code>ShowDetailRow</code> 回调委托可以控制每一行是否显示明细行,本例中通过 <code>Complete</code> 属性来控制是否显示明细行,可通过翻页来测试本功能",
@ -5021,10 +5018,21 @@
"DetailRowTemplate3Title": "明细行中使用 Tab 组件",
"DetailRowTemplate3Intro": "通过设置 <code>DetailRowTemplate</code> 模板设置明细行内容",
"DetailRowTemplate3P": "本例中明细行内使用 <code>Tab</code> 组件再次将数据分割成两个 <code>TabItem</code> 内容,进行再次数据拆分演示",
"TabItemText": "关联数据",
"DynamicTitle": "动态数据明细行",
"DynamicIntro": "数据源为 <code>DataTable</code>"
},
"BootstrapBlazor.Shared.Demos.Table.TablesDetailRow.TablesDetailRowIsDetails": {
"EducationText": "学历:",
"DetailTextTrue": "关闭明细行",
"DetailTextFalse": "开启明细行"
},
"BootstrapBlazor.Shared.Demos.Table.TablesDetailRow.TablesDetailRowHeight": {
"EducationText": "学历:"
},
"BootstrapBlazor.Shared.Demos.Table.TablesDetailRow.TablesDetailRowTemplate": {
"TabItemText": "关联数据",
"EducationText": "学历:"
},
"BootstrapBlazor.Shared.Samples.Table.Tables": {
"ButtonAddColumnText": "增加列",
"ButtonRemoveColumnText": "移除列",

View File

@ -1,110 +1,40 @@
@page "/tables/detail"
@inject IStringLocalizer<TablesDetailRow> Localizer
<h3>@LocalizerDetailRow["Title"]</h3>
<h3>@Localizer["TablesDetailRowTitle"]</h3>
<h4>@LocalizerDetailRow["Desc"]</h4>
<h4>@Localizer["TablesDetailRowDesc"]</h4>
<DemoBlock Title="@LocalizerDetailRow["DetailRowTemplateTitle"]" Introduction="@LocalizerDetailRow["DetailRowTemplateIntro"]" Name="IsDetails">
<p>@((MarkupString)LocalizerDetailRow["DetailRowTemplateP"].Value)</p>
<Table TItem="Foo" @ref="@Table"
IsPagination="true" PageItemsSource="@PageItemsSource"
IsStriped="true" IsBordered="true" IsDetails="IsDetails"
ShowToolbar="true" ShowDefaultButtons="false" ShowRefresh="false" OnDoubleClickRowCallback="OnDoubleClickRowCallback()!"
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>@LocalizerDetailRow["EducationText"] @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
</DetailRowTemplate>
</Table>
<Button Text="@DetailText" OnClick="OnClickDetailRow" class="mt-3"></Button>
<DemoBlock Title="@Localizer["DetailRowTemplateTitle"]"
Introduction="@Localizer["DetailRowTemplateIntro"]"
Name="IsDetails"
Demo="typeof(Demos.Table.TablesDetailRow.TablesDetailRowIsDetails)">
<p>@((MarkupString)Localizer["DetailRowTemplateP"].Value)</p>
</DemoBlock>
<DemoBlock Title="@LocalizerDetailRow["DetailRowTemplate2Title"]" Introduction="@LocalizerDetailRow["DetailRowTemplate2Intro"]" Name="ShowDetailRow">
<p>@((MarkupString)LocalizerDetailRow["DetailRowTemplate2P"].Value)</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>
<Table TItem="DetailRow" IsBordered="true" ShowToolbar="false" Items="@GetDetailDataSource(context)">
<TableColumns Context="Detail">
<TableColumn @bind-Field="@Detail.Name" />
<TableColumn @bind-Field="@Detail.DateTime" Width="180" />
<TableColumn @bind-Field="@Detail.Complete" Width="70" />
</TableColumns>
</Table>
</DetailRowTemplate>
</Table>
<DemoBlock Title="@Localizer["DetailRowTemplate2Title"]"
Introduction="@Localizer["DetailRowTemplate2Intro"]"
Name="Show"
Demo="typeof(Demos.Table.TablesDetailRow.TablesDetailRowShow)">
<p>@((MarkupString)Localizer["DetailRowTemplate2P"].Value)</p>
</DemoBlock>
<DemoBlock Title="@LocalizerDetailRow["HeightTitle"]" Introduction="@LocalizerDetailRow["HeightIntro"]" Name="Height">
<p>@LocalizerDetailRow["HeightP"]</p>
<Table TItem="Foo" Height="400" IsFixedHeader="true"
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>@LocalizerDetailRow["EducationText"] @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
</DetailRowTemplate>
</Table>
<DemoBlock Title="@Localizer["HeightTitle"]"
Introduction="@Localizer["HeightIntro"]"
Name="Height"
Demo="typeof(Demos.Table.TablesDetailRow.TablesDetailRowHeight)">
<p>@Localizer["HeightP"]</p>
</DemoBlock>
<DemoBlock Title="@LocalizerDetailRow["DetailRowTemplate3Title"]" Introduction="@LocalizerDetailRow["DetailRowTemplate3Intro"]" Name="DetailRowTemplate3">
<p>@((MarkupString)LocalizerDetailRow["DetailRowTemplate3P"].Value)</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="明细数据">
<Table TItem="DetailRow" IsBordered="true" ShowToolbar="false" Items="@GetDetailDataSource(context)" AutoGenerateColumns="true" />
</TabItem>
<TabItem Text="@LocalizerDetailRow["TabItemText"]">
<div>@LocalizerDetailRow["EducationText"] @typeof(EnumEducation).ToDescriptionString(context.Education.ToString())</div>
</TabItem>
</Tab>
</DetailRowTemplate>
</Table>
<DemoBlock Title="@Localizer["DetailRowTemplate3Title"]"
Introduction="@Localizer["DetailRowTemplate3Intro"]"
Name="DetailRowTemplate"
Demo="typeof(Demos.Table.TablesDetailRow.TablesDetailRowTemplate)">
<p>@((MarkupString)Localizer["DetailRowTemplate3P"].Value)</p>
</DemoBlock>
<DemoBlock Title="@LocalizerDetailRow["DynamicTitle"]" Introduction="@LocalizerDetailRow["DynamicIntro"]" Name="Excel">
<Table TItem="DynamicObject" DynamicContext="DataTableDynamicContext"
IsStriped="true" IsBordered="true" IsExcel="true"
ShowToolbar="true" ShowDefaultButtons="false">
<DetailRowTemplate>
@{
var detailContext = GetDetailDataTableDynamicContext(context);
}
<div class="p-2 w-100">
<Table TItem="DynamicObject" DynamicContext="detailContext" IsStriped="true" IsBordered="true" IsExcel="true">
</Table>
</div>
</DetailRowTemplate>
</Table>
<DemoBlock Title="@Localizer["DynamicTitle"]"
Introduction="@Localizer["DynamicIntro"]"
Name="Excel"
Demo="typeof(Demos.Table.TablesDetailRow.TablesDetailRowExcel)">
</DemoBlock>

View File

@ -1,143 +0,0 @@
// 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.Shared.Services;
using System.Collections.Concurrent;
using System.ComponentModel;
namespace BootstrapBlazor.Shared.Samples.Table;
/// <summary>
///
/// </summary>
public sealed partial class TablesDetailRow
{
private ConcurrentDictionary<string, List<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; }
[Inject]
[NotNull]
private MockDataTableDynamicService? DataTableDynamicService { get; set; }
[NotNull]
private Table<Foo>? Table { get; set; }
private DataTableDynamicContext? DataTableDynamicContext { get; set; }
/// <summary>
/// OnInitialized 方法
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
DetailText ??= LocalizerDetailRow[$"{nameof(DetailText)}{!IsDetails}"];
Items = Foo.GenerateFoo(Localizer);
DataTableDynamicContext = DataTableDynamicService.CreateContext();
}
private static List<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
}).ToList();
private Func<Foo, Task>? OnDoubleClickRowCallback()
{
Func<Foo, Task>? ret = null;
if (IsDetails)
{
ret = foo =>
{
Table.ExpandDetailRow(foo);
return Task.CompletedTask;
};
}
return ret;
}
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 List<DetailRow> GetDetailDataSource(Foo foo)
{
var cacheKey = foo.Name ?? "";
return Cache.GetOrAdd(cacheKey, key => GetDetailRowsByName(cacheKey));
}
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;
private DynamicObjectContext GetDetailDataTableDynamicContext(DynamicObject context) => DataTableDynamicService.CreateDetailContext(context);
}