mirror of
https://gitee.com/ant-design-blazor/ant-design-blazor.git
synced 2024-11-29 18:48:50 +08:00
feat(module: table): support multiple row grouping (#4089)
* support multiple grouping * fix children * fix rows * fix group data cache and selection * update demo * update style and API
This commit is contained in:
parent
4115dcec69
commit
2b609a1d35
@ -97,7 +97,7 @@ else if (IsBody && RowSpan != 0 && ColSpan != 0)
|
||||
@if (ColIndex == Table.TreeExpandIconColumnIndex && (Table.TreeMode || RowData.IsGrouping))
|
||||
{
|
||||
<span class="ant-table-row-indent indent-level-@RowData.Level" style="padding-left: @((CssSizeLength)(RowData.Level * Table.IndentSize));"></span>
|
||||
@if (DataItem.HasChildren)
|
||||
@if (DataItem.HasChildren || RowData.IsGrouping)
|
||||
{
|
||||
<button type="button" @onclick="ToggleTreeNode" @onclick:stopPropagation class="ant-table-row-expand-icon @(RowData?.Expanded == true ? "ant-table-row-expand-icon-expanded" : "ant-table-row-expand-icon-collapsed")" aria-label="@(RowData?.Expanded == true ? Table.Locale.Collapse : Table.Locale.Expand)"></button>
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ namespace AntDesign
|
||||
}
|
||||
}
|
||||
|
||||
IQueryable<IGrouping<object, TItem>> IFieldColumn.Group<TItem>(IQueryable<TItem> source)
|
||||
Expression<Func<TItem, object>> IFieldColumn.GetGroupByExpression<TItem>()
|
||||
{
|
||||
var param = Expression.Parameter(typeof(TItem), "item");
|
||||
|
||||
@ -413,7 +413,7 @@ namespace AntDesign
|
||||
var body = Expression.Convert(field, typeof(object));
|
||||
var lambda = Expression.Lambda<Func<TItem, object>>(body, param);
|
||||
|
||||
return source.GroupBy(lambda);
|
||||
return lambda;
|
||||
}
|
||||
|
||||
private void SetSorter(SortDirection sortDirection)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using AntDesign.TableModels;
|
||||
@ -34,6 +35,6 @@ namespace AntDesign
|
||||
|
||||
internal void SetSortModel(ITableSortModel sortModel);
|
||||
|
||||
internal IQueryable<IGrouping<object, TItem>> Group<TItem>(IQueryable<TItem> source);
|
||||
internal Expression<Func<TItem, object>> GetGroupByExpression<TItem>();
|
||||
}
|
||||
}
|
||||
|
81
components/table/Internal/MultiLevelDynamicGroupByHelper.cs
Normal file
81
components/table/Internal/MultiLevelDynamicGroupByHelper.cs
Normal file
@ -0,0 +1,81 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Dynamic;
|
||||
using System.Collections.Concurrent;
|
||||
using AntDesign.TableModels;
|
||||
|
||||
namespace AntDesign.Internal;
|
||||
|
||||
internal static class DynamicGroupByHelper
|
||||
{
|
||||
// Cache for storing compiled functions
|
||||
private static readonly ConcurrentDictionary<string, Delegate> _functionCache = new ConcurrentDictionary<string, Delegate>();
|
||||
|
||||
public static List<GroupResult<TEntity>> DynamicGroupBy<TEntity>(
|
||||
IEnumerable<TEntity> source,
|
||||
params Expression<Func<TEntity, object>>[] keySelectors)
|
||||
{
|
||||
return DynamicGroupByInternal(source, keySelectors, 0);
|
||||
}
|
||||
|
||||
private static List<GroupResult<TEntity>> DynamicGroupByInternal<TEntity>(
|
||||
IEnumerable<TEntity> source,
|
||||
Expression<Func<TEntity, object>>[] keySelectors,
|
||||
int level)
|
||||
{
|
||||
if (level >= keySelectors.Length)
|
||||
{
|
||||
return new List<GroupResult<TEntity>>
|
||||
{
|
||||
new GroupResult<TEntity>
|
||||
{
|
||||
Level = level,
|
||||
Key = null,
|
||||
Items = source.ToList()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var keySelector = keySelectors[level];
|
||||
var keySelectorFunc = GetOrAddCachedFunction(keySelector);
|
||||
|
||||
var groupedData = source.GroupBy(keySelectorFunc);
|
||||
|
||||
var result = new List<GroupResult<TEntity>>();
|
||||
|
||||
foreach (var group in groupedData)
|
||||
{
|
||||
var groupKey = group.Key;
|
||||
var children = DynamicGroupByInternal(group.AsQueryable(), keySelectors, level + 1);
|
||||
|
||||
result.Add(new GroupResult<TEntity>
|
||||
{
|
||||
Level = level + 1,
|
||||
Key = groupKey,
|
||||
Children = children,
|
||||
Items = group.ToList()
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Func<TEntity, object> GetOrAddCachedFunction<TEntity>(Expression<Func<TEntity, object>> keySelector)
|
||||
{
|
||||
// Create a unique key by combining the expression string and the entity type
|
||||
var key = $"{typeof(TEntity).FullName}:{keySelector.ToString()}";
|
||||
if (!_functionCache.TryGetValue(key, out var cachedFunc))
|
||||
{
|
||||
cachedFunc = keySelector.Compile();
|
||||
_functionCache.TryAdd(key, cachedFunc);
|
||||
}
|
||||
return (Func<TEntity, object>)cachedFunc;
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ namespace AntDesign
|
||||
|
||||
[Parameter] public string Key { get; set; }
|
||||
|
||||
[Parameter] public bool CheckStrictly { get; set; } = true;
|
||||
[Parameter] public bool CheckStrictly { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public virtual RenderFragment<CellData> CellRender { get; set; }
|
||||
|
@ -230,13 +230,18 @@
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
;
|
||||
}
|
||||
else if (_groupedColumns.Count>0 && level==0)
|
||||
{
|
||||
return _groups.Select((data, index) => GetGroupRowData(data, index, level, parentRowData?.Children))
|
||||
.ForeachLoop(bodyRow());
|
||||
}
|
||||
;
|
||||
}
|
||||
else if (_groupedColumns.Count>0 && level==0)
|
||||
{
|
||||
return _groups.Select((data, index) => GetGroupRowData(data, index, level, parentRowData?.Children))
|
||||
.ForeachLoop(bodyRow());
|
||||
}
|
||||
else if (_groupedColumns.Count>0 && parentRowData?.IsGrouping == true)
|
||||
{
|
||||
return parentRowData?.Children.Values
|
||||
.ForeachLoop(bodyRow());
|
||||
}
|
||||
#if NET5_0_OR_GREATER
|
||||
else if (EnableVirtualization)
|
||||
{
|
||||
@ -259,7 +264,7 @@
|
||||
{
|
||||
return currentRowData =>
|
||||
{
|
||||
return @<TableRowWrapper RowData="currentRowData" @key="currentRowData.RowIndex">
|
||||
return @<TableRowWrapper RowData="currentRowData" @key="currentRowData.Key">
|
||||
@{
|
||||
var currentDataItem = currentRowData.DataItem;
|
||||
var rowAttributes = OnRow?.Invoke(currentRowData);
|
||||
@ -288,10 +293,12 @@
|
||||
</CascadingValue>
|
||||
|
||||
// When expand button was clicked, would trigger here to add one more child level
|
||||
@if (currentDataItem.HasChildren && currentRowData.Expanded)
|
||||
@if ((currentDataItem.HasChildren || currentRowData.IsGrouping) && currentRowData.Expanded)
|
||||
{
|
||||
currentRowData.Children??=new();
|
||||
currentRowData.Children ??= new();
|
||||
currentDataItem.Children ??= [];
|
||||
@body(SortFilterChildren(currentDataItem.Children), currentRowData);
|
||||
@groupFooter(currentRowData);
|
||||
}
|
||||
@if (!currentDataItem.HasChildren && ExpandTemplate != null && RowExpandable(currentRowData) && currentRowData.Expanded)
|
||||
{
|
||||
@ -326,4 +333,17 @@
|
||||
|
||||
return builder => { };
|
||||
}
|
||||
|
||||
RenderFragment groupFooter(RowData<TItem> currentRowData)
|
||||
{
|
||||
@if (GroupFooterTemplate !=null)
|
||||
{
|
||||
return@<tr class="ant-table-expanded-row ant-table-expanded-row-level-1 ant-table-grouping-footer" >
|
||||
<td colspan="@(ColumnContext.Columns.Count+1)" class="ant-table-cell">
|
||||
@GroupFooterTemplate(currentRowData.GroupResult)
|
||||
</td>
|
||||
</tr>;
|
||||
}
|
||||
return builder => { };
|
||||
}
|
||||
}
|
@ -58,7 +58,7 @@ namespace AntDesign
|
||||
}
|
||||
}
|
||||
|
||||
private RowData<TItem> GetGroupRowData(IGrouping<object, TItem> grouping, int index, int level, Dictionary<int, RowData<TItem>> rowCache = null)
|
||||
private RowData<TItem> GetGroupRowData(GroupResult<TItem> grouping, int index, int level, Dictionary<int, RowData<TItem>> rowCache = null)
|
||||
{
|
||||
int rowIndex = index + 1;
|
||||
|
||||
@ -67,18 +67,28 @@ namespace AntDesign
|
||||
rowIndex += PageSize * (PageIndex - 1);
|
||||
}
|
||||
|
||||
var groupRowData = new RowData<TItem>()
|
||||
var hashCode = grouping.GetHashCode();
|
||||
rowCache ??= _rootRowDataCache;
|
||||
|
||||
if (!rowCache.TryGetValue(hashCode, out var groupRowData) || groupRowData == null)
|
||||
{
|
||||
Key = grouping.Key.ToString(),
|
||||
IsGrouping = true,
|
||||
RowIndex = rowIndex,
|
||||
DataItem = new TableDataItem<TItem>
|
||||
groupRowData = new RowData<TItem>()
|
||||
{
|
||||
Table = this,
|
||||
Children = grouping
|
||||
},
|
||||
Children = grouping.Select((data, index) => GetRowData(data, index, level, rowCache)).ToDictionary(x => GetHashCode(x.Data), x => x)
|
||||
};
|
||||
Key = grouping.Key.ToString(),
|
||||
IsGrouping = true,
|
||||
RowIndex = rowIndex,
|
||||
Level = level,
|
||||
GroupResult = grouping,
|
||||
DataItem = new TableDataItem<TItem>
|
||||
{
|
||||
Table = this,
|
||||
},
|
||||
Children = grouping.Children.SelectMany(x => x.Key == null ? x.Items.Select((data, index) => GetRowData(data, index + rowIndex, level + 1, rowCache)) : [GetGroupRowData(x, index + rowIndex, level + 1, rowCache)])
|
||||
.ToDictionary(x => x.Data != null ? GetHashCode(x.Data) : x.GroupResult.GetHashCode(), x => x)
|
||||
};
|
||||
|
||||
rowCache.Add(hashCode, groupRowData);
|
||||
}
|
||||
|
||||
return groupRowData;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ using AntDesign.core.Services;
|
||||
using AntDesign.Table.Internal;
|
||||
using AntDesign.Core.Reflection;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using AntDesign.Internal;
|
||||
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
@ -67,7 +68,10 @@ namespace AntDesign
|
||||
public RenderFragment<TItem> ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment<RowData<TItem>> GroupTitleTemplate { get; set; }
|
||||
public RenderFragment<GroupResult<TItem>> GroupTitleTemplate { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment<GroupResult<TItem>> GroupFooterTemplate { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment<RowData<TItem>> RowTemplate { get; set; }
|
||||
@ -234,7 +238,7 @@ namespace AntDesign
|
||||
|
||||
private QueryModel _currentQueryModel;
|
||||
private readonly ClassMapper _wrapperClassMapper = new();
|
||||
private List<IGrouping<object, TItem>> _groups = [];
|
||||
private List<GroupResult<TItem>> _groups = [];
|
||||
|
||||
private string TableLayoutStyle => TableLayout == null ? "" : $"table-layout: {TableLayout};";
|
||||
|
||||
@ -283,16 +287,17 @@ namespace AntDesign
|
||||
|
||||
RenderFragment<RowData> ITable.GroupTitleTemplate => rowData =>
|
||||
{
|
||||
var groupResult = ((RowData<TItem>)rowData).GroupResult;
|
||||
if (GroupTitleTemplate == null)
|
||||
{
|
||||
return builder =>
|
||||
{
|
||||
builder.AddContent(0, rowData.Key);
|
||||
builder.AddContent(0, groupResult.Key);
|
||||
};
|
||||
}
|
||||
return builder =>
|
||||
{
|
||||
builder.AddContent(0, GroupTitleTemplate((RowData<TItem>)rowData));
|
||||
builder.AddContent(0, GroupTitleTemplate(groupResult));
|
||||
};
|
||||
};
|
||||
|
||||
@ -607,28 +612,18 @@ namespace AntDesign
|
||||
return;
|
||||
}
|
||||
|
||||
var queryModel = BuildQueryModel();
|
||||
var query = queryModel.ExecuteQuery(_dataSource.AsQueryable());
|
||||
|
||||
foreach (var column in _groupedColumns)
|
||||
{
|
||||
var grouping = column.Group(queryModel.CurrentPagedRecords(query));
|
||||
_groups = [.. grouping];
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
var selectedKeys = _groupedColumns.Select(x => x.GetGroupByExpression<TItem>()).ToArray();
|
||||
_groups = DynamicGroupByHelper.DynamicGroupBy(_showItems, selectedKeys);
|
||||
}
|
||||
|
||||
public void AddGroupColumn(IFieldColumn column)
|
||||
{
|
||||
this._groupedColumns.Add(column);
|
||||
GroupItems();
|
||||
}
|
||||
|
||||
public void RemoveGroupColumn(IFieldColumn column)
|
||||
{
|
||||
this._groupedColumns.Remove(column);
|
||||
GroupItems();
|
||||
}
|
||||
|
||||
private void SetClass()
|
||||
|
21
components/table/TableModels/GroupResult.cs
Normal file
21
components/table/TableModels/GroupResult.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AntDesign.TableModels;
|
||||
|
||||
public class GroupResult<TEntity>
|
||||
{
|
||||
public int Level { get; set; }
|
||||
public object Key { get; set; }
|
||||
internal List<GroupResult<TEntity>> Children { get; set; } = [];
|
||||
public List<TEntity> Items { get; set; } = [];
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Items);
|
||||
}
|
||||
}
|
@ -21,6 +21,8 @@ namespace AntDesign.TableModels
|
||||
/// </summary>
|
||||
public Dictionary<int, RowData<TItem>> Children { get; set; }
|
||||
|
||||
public GroupResult<TItem> GroupResult { get; set; }
|
||||
|
||||
public RowData()
|
||||
{ }
|
||||
|
||||
|
@ -92,4 +92,13 @@
|
||||
border-right: 2px dashed @primary-color-active;
|
||||
z-index: 99;
|
||||
}
|
||||
}
|
||||
|
||||
tr.@{table-prefix-cls}-grouping-footer > td {
|
||||
padding: 0;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
tr.@{table-prefix-cls}-row-grouping > td {
|
||||
padding: @table-padding-vertical-sm @table-padding-horizontal-sm;
|
||||
}
|
@ -1,39 +1,31 @@
|
||||
@using System.ComponentModel
|
||||
|
||||
<Table DataSource="data">
|
||||
<GroupTitleTemplate Context="rowData">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<span style="min-width: 120px;">
|
||||
@rowData.Key
|
||||
</span>
|
||||
<span style="margin-left: -30px;">
|
||||
@if (rowData.Key == "A")
|
||||
{
|
||||
<Tag Color="red-inverse">Excellent</Tag>
|
||||
}
|
||||
else if (rowData.Key == "B")
|
||||
{
|
||||
<Tag Color="purple-inverse">Good</Tag>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Tag Color="rgb(143, 201, 146)">Average</Tag>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
<Table DataSource="data" Bordered>
|
||||
<GroupTitleTemplate Context="group">
|
||||
<span style="min-width: 120px;">
|
||||
@(group.Level == 1 ? "Subject" : "Grade") : @group.Key
|
||||
</span>
|
||||
</GroupTitleTemplate>
|
||||
<GroupFooterTemplate Context="group">
|
||||
@if (group.Level == 1)
|
||||
{
|
||||
<span style="padding: 8px; float: right; ">
|
||||
Total: @group.Items.Sum(x => x.Score)
|
||||
</span>
|
||||
}
|
||||
</GroupFooterTemplate>
|
||||
<ColumnDefinitions>
|
||||
<Selection />
|
||||
<PropertyColumn Property="c=>c.Name" />
|
||||
<PropertyColumn Property="c=>c.Age" Width="12%" Sortable />
|
||||
<PropertyColumn Property="c=>c.Subject" Width="30%" />
|
||||
<PropertyColumn Property="c=>c.Grade" Width="30%" Grouping GroupBy="GradeGroupBy" />
|
||||
<PropertyColumn Property="c=>c.Name" Grouping />
|
||||
<PropertyColumn Property="c=>c.Age" Width="12%" />
|
||||
<PropertyColumn Property="c=>c.Subject" Width="30%" />
|
||||
<PropertyColumn Property="c=>c.Score" Width="30%" Grouping GroupBy="GradeGroupBy" Sortable />
|
||||
</ColumnDefinitions>
|
||||
</Table>
|
||||
|
||||
@code {
|
||||
string GradeGroupBy(int grade)
|
||||
=> grade switch
|
||||
string GradeGroupBy(int score)
|
||||
=> score switch
|
||||
{
|
||||
>= 95 => "A",
|
||||
>= 90 => "B",
|
||||
@ -45,38 +37,38 @@
|
||||
new() {
|
||||
Name = "John Brown",
|
||||
Age = 10,
|
||||
Grade = 90,
|
||||
Subject= "Math"
|
||||
},
|
||||
new() {
|
||||
Name = "John Brown",
|
||||
Age = 10,
|
||||
Grade = 95,
|
||||
Score = 95,
|
||||
Subject= "Language"
|
||||
},
|
||||
new() {
|
||||
Name = "John Brown",
|
||||
Age = 10,
|
||||
Grade = 85,
|
||||
Score = 90,
|
||||
Subject= "Math"
|
||||
},
|
||||
new() {
|
||||
Name = "John Brown",
|
||||
Age = 10,
|
||||
Score = 85,
|
||||
Subject="Science"
|
||||
},
|
||||
new() {
|
||||
Name = "Harry Potter",
|
||||
Age = 10,
|
||||
Grade = 89,
|
||||
Subject= "Math"
|
||||
Age = 9,
|
||||
Score = 95,
|
||||
Subject="Science"
|
||||
},
|
||||
new() {
|
||||
Name = "Harry Potter",
|
||||
Age = 10,
|
||||
Grade = 90,
|
||||
Age = 9,
|
||||
Score = 90,
|
||||
Subject= "Language"
|
||||
},
|
||||
new() {
|
||||
Name = "Harry Potter",
|
||||
Age = 10,
|
||||
Grade = 95,
|
||||
Subject="Science"
|
||||
Age = 9,
|
||||
Score = 89,
|
||||
Subject= "Math"
|
||||
},
|
||||
};
|
||||
|
||||
@ -86,7 +78,7 @@
|
||||
|
||||
public int Age { get; set; }
|
||||
|
||||
public int Grade { get; set; }
|
||||
public int Score { get; set; }
|
||||
|
||||
public string Subject { get; set; }
|
||||
}
|
||||
|
@ -7,14 +7,15 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
设置 `Grouping` 指定根据某列字段分组,也可以设置 `GroupBy` 委托设置分组的值。当前只支持一个属性。
|
||||
设置 `Grouping` 指定列属性值进行分组,也可以设置 `GroupBy` 委托来指定分组的值。还可以设置 `GroupTitleTemplate` 自定义分组标题。
|
||||
|
||||
还可以设置 `GroupTitleTemplate` 自定义分组标题。
|
||||
**注意:目前实现的是客户端分组,因此如果 `DataSource` 绑定的是 `IQueryable<T>`,请确保其已包含数据库分组的操作(分页、排序和筛选仍然生效)**
|
||||
|
||||
## en-US
|
||||
|
||||
Setting `Grouping` Specifies that grouping is based on a column field.
|
||||
You can also set the `GroupBy` delegate to set the value for grouping.
|
||||
Currently only one attribute is supported.
|
||||
Set `Grouping` to specify the column property values for grouping,
|
||||
and you can also set `GroupBy` delegation to specify the grouping values.
|
||||
You can also set `GroupTitleTemplate` to customize the group title.
|
||||
|
||||
You can also set `GroupTitleTemplate` to customize the group title.
|
||||
**Note: Currently implementation is client-side grouping ,
|
||||
so if `DataSource` is bound to `IQueryable<T>`, make sure it includes database grouping operations (paging, sorting, and filtering are still in effect)**
|
@ -54,6 +54,7 @@ Since 0.16.0, Table has supported ordinary classes, record, interface, and abstr
|
||||
| Title | Table title | string | - |
|
||||
| TitleTemplate | Title template | RenderFragment | - |
|
||||
| GroupTitleTemplate | Row group title template | RenderFragment | - |
|
||||
| GroupFooterTemplate | Group foot template, often used to aggregate statistics | RenderFragment<GroupResult<TItem>> | - |
|
||||
| Footer | Table Footer | string | - |
|
||||
| FooterTemplate | Footer Template | RenderFragment | - |
|
||||
| Size | Table Size | [TableSize](https://github.com/ant-design-blazor/ant-design-blazor/blob/master/components/table/TableSize.cs) | - |
|
||||
@ -75,6 +76,7 @@ Since 0.16.0, Table has supported ordinary classes, record, interface, and abstr
|
||||
| Resizable | Enable resizable column | bool | false |
|
||||
| FieldFilterTypeResolver | Used to resolve filter types for columns | `IFilterTypeResolver` | Injected |
|
||||
|
||||
|
||||
### Column
|
||||
|
||||
The Column definition of the previous version, For .NET 6 and above, `PropertyColumn` is recommended.
|
||||
@ -99,6 +101,8 @@ The Column definition of the previous version, For .NET 6 and above, `PropertyCo
|
||||
| FilterDropdown | Custom Filter Dropdown Template | RenderFragment | - |
|
||||
| FieldFilterType | Specifies what filter options to display and how to filter the data | `IFieldFilterType` | Resolved using Table's `FieldFilterTypeResolver` |
|
||||
| Filtered | Whether the dataSource is filtered. Filter icon will be actived when it is true. | bool | false |
|
||||
| Grouping | Specify that this column is used for grouping | bool | - |
|
||||
| GroupBy | A delegate that converts the value of a group | Func<TData, object> | - |
|
||||
|
||||
### PropertyColumn
|
||||
|
||||
|
@ -53,7 +53,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
|
||||
| Loading | 表格是否加载中 | bool | false |
|
||||
| Title | 表格标题 | string | - |
|
||||
| TitleTemplate | 标题模板 | RenderFragment | - |
|
||||
| GroupTitleTemplate | 行分组标题模板 | RenderFragment | - |
|
||||
| GroupTitleTemplate | 分组标题模板,不设置默认标题为该层级分组 Key 的字符串转换 | RenderFragment<GroupResult<TItem>> | - |
|
||||
| GroupFooterTemplate | 分组脚部模板,常用于对分组的统计 | RenderFragment<GroupResult<TItem>> | - |
|
||||
| Footer | 表格尾部 | string | - |
|
||||
| FooterTemplate | 表格尾部模板 | RenderFragment | - |
|
||||
| Size | 表格尺寸大小 | [TableSize](https://github.com/ant-design-blazor/ant-design-blazor/blob/master/components/table/TableSize.cs) | - |
|
||||
@ -99,7 +100,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
|
||||
| FilterDropdown | 自定义列筛选器模板 | RenderFragment | - |
|
||||
| FieldFilterType | 筛选器配置 ,可用于自定义额外的筛选器 | `IFieldFilterType` | 由 `FieldFilterTypeResolver` 根据类型解析内置筛选器 |
|
||||
| OnFilter | 筛选当前数据 | Expression<Func<TData, TData, bool>> | - |
|
||||
|
||||
| Grouping | 指定该列用于分组 | bool | - |
|
||||
| GroupBy | 一个委托,用于转换分组的值 | Func<TData, object> | - |
|
||||
|
||||
### PropertyColumn
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user