Blazor 自定义可重用基础组件之 Table

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();
        }
    }

}

效果图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落单枫叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值