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'); }); }
关键修复说明
- 修正异步方法定义:将
OnWindowResize改为async Task,并在初始化时await调用,确保初始化阶段就能正确计算页大小。 - 触发UI更新:修改
gridPageSize后调用StateHasChanged(),通知Blazor重新渲染组件,更新Grid的PageSize绑定值。 - 强制刷新Grid:调用
grid.RefreshAsync(),让Grid使用新的页大小重新拉取数据。 - 窗口事件监听与防抖:通过JSInterop注册窗口
resize事件,添加防抖处理避免频繁触发计算,提升性能。 - 资源清理:实现
IDisposable接口,组件销毁时移除事件监听并释放对象引用,防止内存泄漏。
另外,不建议在DataProvider中调用OnWindowResize——DataProvider会在分页、排序、过滤操作时频繁触发,重复计算页大小会造成性能浪费。
内容的提问来源于stack exchange,提问作者Ravi Makwana
相关产品推荐
相关产品推荐

