mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-12-02 03:59:14 +08:00
doc: update the table component detailrow demos (#483)
Co-authored-by: Argo Zhang <argo@live.ca>
This commit is contained in:
parent
ba880397df
commit
936b4a7fea
@ -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);
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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",
|
||||
|
@ -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": "移除列",
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user