Blazor - 表列组件的 SortBy 参数

问题描述 投票:0回答:2

我正在使用 Blazor,希望能够通过采用 lambda 表达式的 SortBy 参数按给定列对数据网格(表)进行排序。它看起来像这样:

<DataGrid Items="Orders">
  <GridHeader>
    <GridColumn Label="Order Number" SortBy="@(order => order.OrderNumber)" />
    <GridColumn Label="Order Date" SortBy="@(order => order.Date)" />
    <GridColumn Label="Order Status" SortBy="@(order => order.Status)" />
    <GridColumn Label="Number of Line Items" SortBy="@(order => order.LineItems.Count)" />
  </GridHeader>
  <GridRow Context="order">
    <td>@order.OrderNumber</td>
    <td>@order.OrderDate</td>
    <td>@order.Status</td>
    <td>@order.LineItems.Count</td>
  </GridRow>
</Table>

Grid 组件应该能够采用任何类型的

IEnumerable
(如
IEnumerable<Order>
),因此
<DataGrid>
组件应该具有与其行项目关联的通用类型,通过
@typeparam TableItem
设置。我遇到的问题是能够在
TableItem
GridColumn
参数中引用
SortBy
类型。我需要它,以便我的代码编辑器 (Visual Studio) 识别
TableItem
lambda 表达式中的
SortBy
类型,以便(在本例中)当我开始输入
SortBy="@(order => order.)"
时,它将订单识别为类型
Order
智能感知将显示该类型的属性。我认为该解决方案与使用级联参数 (
CascadingValue
) 和
@typeparam
有关,但我一直无法让它工作,并且想知道 Blazor 是否存在当前限制,导致其无法工作(例如,请参阅 this github issues,该问题仍处于开放状态)。

这是否可能,如果可以,我应该在这里使用什么方法?

c# lambda blazor type-parameter
2个回答
3
投票

抱歉,我没有给你直接的答案,但你可以看到这个项目的可排序和可过滤表,包括 lambda 表达式。我正在我的项目中使用它,目前运行良好。希望您觉得它有用:)。 Blazor 可排序表


0
投票

我不完全理解 - 您是否想要指定每列如何单独排序,或者您想要指定通过网格中表示的实体的哪些属性来排序所有项目? 第一个没有意义,因为列之间没有任何关系。后者更有意义,并且实际上更接近我的做法,但我不会将其称为

SortBy
,我宁愿将其称为
Property
,因为您可以使用该表达式指定该列中表示的属性,但是让我详细说明一下...

通常,如何做到这一点在很大程度上取决于组件的构成方式。我自己也尝试开发一个 DataGrid 组件,最终我在 this 之上进行构建。我对它进行了很多定制,其中之一就是排序。它实际上比你想象的要容易得多。

链接中示例的工作方式是:您使用列上的表达式指定属性。然后可以编译该表达式并使用它来提取从指定实体表示的属性值(尝试深入研究代码,它位于 GridColumns

CellTemplate
中)。
<th>
<td>
元素正在与
RenderTreebuilder
一起构建。

现在要实现排序,您可以执行以下操作并在 DataGrid 上创建一个公共方法

.SortItems(Func<TEntity, object> sortFunc)
,该方法接受指定要排序的属性的 func。这可以是设置该列表示的属性时指定的表达式。
SortFunc
可以直接使用
.OrderBy()
.OrderByDescending()
应用于您的项目列表,然后再将其传递到标记。

// ChildGridColumn
// Method being called when clicking a column header, passes along property func
private void OnSort()
{
    if (CompiledProperty != null)
        ParentDataGrid?.SortItems(CompiledProperty);
}

// ParentGrid
// SortMode differentiating ascending and descending sort modes.
public enum SortMode
{
    Ascending,
    Descending,
}

// Method sets the specfified sortFunc, provided by the GridColumn
public void SortItems(Func<TEntity, object> sortFunc)
{
    SortFunc = sortFunc;

    if (SortMode == SortMode.Ascending)
        SortMode = SortMode.Descending;
    else if (SortMode == SortMode.Descending)
        SortMode = SortMode.Ascending;

    StateHasChanged();
}

// Method sorts according to the SortMode
private IEnumerable<TEntity> GetSortedItems()
{
    return SortMode switch
    {
        SortMode.Descending => Items.OrderByDescending(SortFunc),
        SortMode.Ascending or _ => Items.OrderBy(SortFunc),
    };
}

如果您想知道如何向由

RenderTreeBuilder
构建的 HTML 元素添加事件处理程序,这里还有另一个简短的示例:

var style = GetHeaderStyle();
var clickEvent = EventCallback.Factory.Create<MouseEventArgs>(this, OnSort);

builder.OpenElement(0, "td");

builder.AddAttribute(1, "width", Width);
builder.AddAttribute(2, "style", style);
builder.AddAttribute(3, "onclick", clickEvent);
builder.AddAttribute(4, "onmouseleave", hoverEvent);
builder.AddContent(5, title);

builder.CloseElement();

你应该查一下,它很容易学习,并且有足够多的表达能力的资源。

© www.soinside.com 2019 - 2024. All rights reserved.