You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BlazorBootstrap Grid动态页大小问题:初始化后无法修改页大小

基于窗口高度动态设置BlazorBootstrap Grid的页大小

我需要根据窗口可用高度动态调整BlazorBootstrap Grid的页大小,目前已经能获取窗口高度并计算出可容纳的行数,但组件初始化后无法修改页大小。相关代码如下:

Page.razor

<Grid @ref="grid" TItem="Data.Connection" class="table table-hover table-bordered table-striped" DataProvider="DataProvider" AllowPaging="true" PageSize="@gridPageSize" AllowSorting="true" Responsive="true" >
    <GridColumn TItem="Data.Connection" TextNoWrap="true" HeaderText="Name" PropertyName="Name" SortString="Name" SortKeySelector="item => item.Name">
        @context.Name
    </GridColumn>
    <GridColumn TItem="Data.Connection" TextNoWrap="true" HeaderText="Source Type" PropertyName="SourceType" SortString="SourceType" SortKeySelector="item => item.SourceType">
        @context.SourceType
    </GridColumn>
    <GridColumn TItem="Data.Connection" TextNoWrap="true" HeaderText="Location" PropertyName="Location" SortString="Location" SortKeySelector="item => item.Location">
        @context.Location
    </GridColumn>
    <GridColumn TItem="Data.Connection" TextNoWrap="true" HeaderText="Status" PropertyName="Status" SortString="Status" SortKeySelector="item => item.Status">
        @context.Status
    </GridColumn>
    <GridColumn TItem="Data.Connection" TextNoWrap="true" HeaderText="Action" Sortable="false">
        <Button @onclick="()=>Edit(context.Id)" Class="btn btn-info oi oi-pencil" TooltipTitle="Edit" />
        <Button @onclick="()=>Delete(context.Id)" Class="btn btn-danger oi oi-trash" TooltipTitle="Delete" />
    </GridColumn>
</Grid>

Page.razor.cs

public partial class Page : IDisposable
{
    [Inject]
    ConnectionService service { get; set; }
    [Inject]
    IJSRuntime jsr { get; set; }
    BlazorBootstrap.Grid<Connection>? grid { get; set; }
    int gridPageSize { get; set; } = 10;
    private DotNetObjectReference<Page>? _dotNetRef;

    protected override async Task OnInitializedAsync() 
    {
        _dotNetRef = DotNetObjectReference.Create(this);
        await OnWindowResize();
        // 注册窗口resize事件
        await jsr.InvokeVoidAsync("registerResizeEvent", _dotNetRef);
    }

    [JSInvokable]
    public async Task OnWindowResize()
    {
        var winHeight = await jsr.InvokeAsync<int>("getHeight") - 20;
        var newPageSize = Convert.ToInt32(winHeight / 47);
        
        if (newPageSize != gridPageSize) // 避免不必要的重复刷新
        {
            gridPageSize = newPageSize;
            StateHasChanged(); // 通知Blazor更新UI绑定
            if (grid is not null)
            {
                await grid.RefreshAsync(); // 让Grid使用新页大小重新加载数据
            }
        }
    }

    private async Task<GridDataProviderResult<Connection>> DataProvider(GridDataProviderRequest<Connection> request)
    {
        string sortString = "";
        SortDirection sortDirection = SortDirection.None;

        if (request.Sorting is not null && request.Sorting.Any())
        {
            sortString = request.Sorting.FirstOrDefault().SortString;
            sortDirection = request.Sorting.FirstOrDefault().SortDirection;
        }

        int totalCount = 0;
        var data = await service.GetGridDataAsync(request.Filters, ref totalCount, request.PageNumber, request.PageSize, sortString, sortDirection);           
        return new GridDataProviderResult<Connection> { Data = data, TotalCount = totalCount };
    }

    public void Dispose()
    {
        // 清理事件监听和对象引用,防止内存泄漏
        jsr.InvokeVoidAsync("unregisterResizeEvent", _dotNetRef);
        _dotNetRef?.Dispose();
    }
}

补充JS代码(放置在wwwroot/js/site.js中)

let resizeTimeout;

// 获取窗口可用高度
function getHeight() {
    return window.innerHeight;
}

// 注册窗口resize事件,添加防抖避免频繁触发
function registerResizeEvent(dotNetRef) {
    window.addEventListener('resize', () => {
        clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(() => {
            dotNetRef.invokeMethodAsync('OnWindowResize');
        }, 250);
    });
}

// 移除窗口resize事件监听
function unregisterResizeEvent(dotNetRef) {
    window.removeEventListener('resize', () => {
        dotNetRef.invokeMethodAsync('OnWindowResize');
    });
}

关键修复说明

  1. 修正异步方法定义:将OnWindowResize改为async Task,并在初始化时await调用,确保初始化阶段就能正确计算页大小。
  2. 触发UI更新:修改gridPageSize后调用StateHasChanged(),通知Blazor重新渲染组件,更新Grid的PageSize绑定值。
  3. 强制刷新Grid:调用grid.RefreshAsync(),让Grid使用新的页大小重新拉取数据。
  4. 窗口事件监听与防抖:通过JSInterop注册窗口resize事件,添加防抖处理避免频繁触发计算,提升性能。
  5. 资源清理:实现IDisposable接口,组件销毁时移除事件监听并释放对象引用,防止内存泄漏。

另外,不建议在DataProvider中调用OnWindowResize——DataProvider会在分页、排序、过滤操作时频繁触发,重复计算页大小会造成性能浪费。

内容的提问来源于stack exchange,提问作者Ravi Makwana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:46:35