Table 组件比较复杂,内容比较多。
页面代码如下:
@typeparam T
<style>
th {
text-align: center;
font-weight: 500;
font-size: 16px;
white-space: nowrap;
}
td {
font-size: 14.66px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 25px;
}
</style>
<div>
@ToolBarContent
</div>
<div>
<table class="table table-bordered table-hover table-sm table-striped">
<thead>
<tr>
@foreach (var item in HeaderTitles)
{
<th>@item</th>
}
</tr>
</thead>
<tbody>
@if (PageData.HasData)
{
foreach (var item in PageData)
{
<tr @onclick="()=>OnRowClick(item)" >
@RowContent(item)
</tr>
}
}
else
{
<tr>
<td colspan="@ColumnsCount" class="text-center">暂无数据</td>
</tr>
}
</tbody>
</table>
<div class="row col-12 justify-content-end">
<button class="btn btn-primary btn-sm" disabled="@PageData.NoPreviousPage" @onclick="()=>GotoPage(1)" style="width:80px;height:30px;">首页</button>
<button class="btn btn-primary btn-sm" disabled="@PageData.NoPreviousPage" @onclick="PreviousPage" style="width:80px;height:30px;">上一页</button>
<button class="btn btn-primary btn-sm" disabled="@PageData.NoNextPage" @onclick="NextPage" style="width:80px;height:30px;">下一页</button>
<button class="btn btn-primary btn-sm" disabled="@PageData.NoNextPage" @onclick="()=>GotoPage(PageData.TotalPages)" style="width:60px;height:30px;">尾页</button>
<input type="number" style="width:60px;height:30px;" @bind-value="pageNum" />
<button class="btn btn-primary btn-sm" disabled="@PageData.NoGoto" @onclick="()=>GotoPage(pageNum)" style="width:60px;height:30px;">跳转</button>
<p class="mx-4" style="width:130px;height:30px;">总页数:@PageData.TotalPages</p>
<p style="width:130px;height:30px;">当前页:@pageIndex</p>
<p style="width:130px;height:30px;">总条数:@PageData.ItemCount</p>
</div>
</div>
C#代码如下:
public partial class Table<T> : ComponentBase where T : class
{
private int pageIndex = 1;
private int pageSize = 15;
private int pageNum;
private IQueryable<T>? query;
private PaginatedList<T> PageData { get; set; } = new(new List<T>(), 0, 1, 1);
[Parameter]
public RenderFragment? ToolBarContent { get; set; }
[Parameter]
public required Array HeaderTitles { get; set; }
[Parameter]
public required RenderFragment<T> RowContent { get; set; }
//[Parameter]
//public RenderFragment<RenderFragment>? RowTemplate { get; set; }
[Parameter]
public EventCallback<T> OnRowClickCallback { get; set; }
public async void OnRowClick(T item)
{
if (OnRowClickCallback.HasDelegate)
await OnRowClickCallback.InvokeAsync(item);
}
private int ColumnsCount;
protected override void OnParametersSet()
{
base.OnParametersSet();
ColumnsCount = HeaderTitles.Length;
}
public int PageSize
{
get => pageSize;
set
{
if (value != pageSize)
{
pageSize = value;
OnChange();
}
}
}
public IQueryable<T> Query
{
get => query ?? (new List<T>()).AsQueryable();
set
{
if (value != query)
{
query = value;
OnChange();
}
}
}
private void OnChange()
{
PageData = PaginatedList<T>.Create(Query, pageIndex, PageSize);
StateHasChanged();
}
private void PreviousPage()
{
pageIndex--;
OnChange();
}
private void NextPage()
{
pageIndex++;
OnChange();
}
private void GotoPage(int pageNum)
{
if (pageNum > 0 && pageNum != pageIndex && pageNum <= PageData.TotalPages)
{
pageIndex = pageNum;
OnChange();
}
}
}
PaginatedList 代码以前贴过,这里只增加一个属性ItemCount。
Blazor Server 客户端分页类_落单枫叶的博客-CSDN博客
使用:
@inject IDataService DataService
<Table @ref="myTable" T="Company" OnRowClickCallback="(e)=> edit(e.Id)" HeaderTitles="headerTitles">
<ToolBarContent>
<div class="row col-12 justify-content-between">
<p style="width:auto;font-size:20px;font-weight:500;"><b>客户列表</b></p>
<p style="width:120px;">
<button class="btn btn-primary btn-sm" @onclick="addCompany">新添加</button>
</p>
<p style="width:auto;">
<label class="form-label">
选择区域
<select class="form-control-sm mt-0" @onchange="SearchDistChanged">
<option value="">全部</option>
@foreach (var item in distFilters)
{
<option value="@item">@item</option>
}
</select>
</label>
</p>
<p style="width:auto;">
<input @onchange="SearchNameChanged" placeholder="单位名称查询" class="form-control-sm mt-0" />
</p>
</div>
</ToolBarContent>
<RowContent>
<td>@context.Name</td>
<td>@context.ManagerName</td>
<td>@context.DistrictName</td>
<td>@context.Adress</td>
</RowContent>
</Table>
@code {
private IEnumerable<Company> dataSource = new List<Company>();
private string _searchString = "", _searchdist = "";
private Array headerTitles = new string[]{ "名称", "业主","区域","地址"};
private IQueryable<Company> Query
{
get
{
if (myTable != null)
{
return myTable.Query;
}
return (new List<Company>()).AsQueryable();
}
set
{
if (myTable != null)
{
myTable.Query = value;
}
}
}
private Table<Company>? myTable;
IList<string> distFilters = new List<string>();
private void SearchDistChanged(ChangeEventArgs e)
{
_searchdist = e.Value?.ToString() ?? "";
onChanged();
}
private void SearchNameChanged(ChangeEventArgs e)
{
_searchString = e.Value?.ToString() ?? "";
onChanged();
}
protected override async Task OnInitializedAsync()
{
dataSource = await DataService.GetCompaniesAsync();
if (dataSource.Any())
{
IQueryable<string> distQuery = from m in dataSource.AsQueryable()
orderby m.DistrictName
select m.DistrictName;
foreach (var item in distQuery.Distinct().ToArray())
{
distFilters.Add(item);
}
}
}
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
if (firstRender)
{
Query = dataSource.AsQueryable().OrderBy(o => o.DistrictName);
}
}
private void onChanged()
{
Query = dataSource.AsQueryable()
.Where(x => string.IsNullOrWhiteSpace(_searchString) || x.Name.Contains(_searchString, StringComparison.OrdinalIgnoreCase))
.Where(x => string.IsNullOrWhiteSpace(_searchdist) || x.DistrictName == _searchdist);
}
private async void addCompany()
{
//代码略
}
private async void edit(int id)
{
//代码略
}
}
改造的FetchData.razor
@page "/fetchdata"
@using MySoft.Data
@inject WeatherForecastService ForecastService
<PageTitle>Weather forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from a service.</p>
<Table @ref="myTable" HeaderTitles="headerTitles" T="WeatherForecast">
<RowContent>
<td>@context.Date.ToShortDateString()</td>
<td>@context.TemperatureC</td>
<td>@context.TemperatureF</td>
<td>@context.Summary</td>
</RowContent>
</Table>
@code {
private WeatherForecast[] forecasts = new WeatherForecast[] { };
private YtTable<WeatherForecast>? myTable;
private Array headerTitles = new string[]
{
"Date","Temp. (C)","Temp. (F)","Summary"
};
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
}
private IQueryable<WeatherForecast> Query
{
get
{
if (myTable != null)
{
return myTable.Query;
}
return (new List<WeatherForecast>()).AsQueryable();
}
set
{
if (myTable != null)
{
myTable.Query = value;
}
}
}
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
if (firstRender)
{
Query = forecasts.AsQueryable();
}
}
}
效果图: