接上篇文章 对于 Blazor 组件虚拟化支持flex-wrap: wrap与网格布局的研究 [一]
自适应
可以试封装成组件, 公开 itemsPerRow 和 itemsHeight 等参数, 配合查询父元素/屏幕宽度,就能自适应调节了.
在 Blazor 组件中使用 JavaScript 互操作来查询 id="div-test" 元素的渲染宽度。以下是如何实现的步骤:
- 在 wwwroot/index.html 文件中添加一个 JavaScript 函数来获取元素的宽度:
<script>
window.getElementWidth = (elementId) => {
const element = document.getElementById(elementId);
return element ? element.offsetWidth : 0;
};
</script>
- 在 Virtualized.razor 文件中使用 JSRuntime 调用这个 JavaScript 函数,并在 OnAfterRenderAsync 方法中获取元素的宽度。
@page "/"
<PageTitle>Virtualized Orders</PageTitle>
<h1>Virtualized Orders</h1>
<div id="div-test" style="height: 370px; overflow-y: scroll; width: 380px; ">
<Virtualize Items="GroupedOrders" Context="orderGroup" ItemSize="16.667f">
<div style="display: flex; flex-direction: row; flex-wrap: wrap; ">
@foreach (var order in orderGroup)
{
<div style="width: 100px; height: 100px; background-color: cadetblue; padding: 10px; margin: 10px;">
<div>$ @order.Value</div>
</div>
}
</div>
</Virtualize>
</div>
<p>元素宽度: @elementWidth px</p>
@code {
private int elementWidth;
int itemsPerRow = 3;
public record Order(Guid Id, int Value);
public IList<Order> Orders { get; set; } = new List<Order>();
public IList<IEnumerable<Order>>? GroupedOrders { get; set; }
[Inject]
private IJSRuntime JSRuntime { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
elementWidth = await JSRuntime.InvokeAsync<int>("getElementWidth", "div-test");
StateHasChanged();
}
}
protected override void OnInitialized()
{
var random = new Random();
for (int i = 0; i < 100; i++)
{
Orders.Add(new Order(Guid.NewGuid(), random.Next(20, 9999)));
}
GroupedOrders = Orders
.Select((order, index) => new { order, index })
.GroupBy(x => x.index / itemsPerRow)
.Select(g => g.Select(x => x.order))
.ToList();
}
}
加入自动计算
<div id="div-test" style="height: 370px; overflow-y: scroll; width: 70vw; ">
@if (GroupedOrders != null)
{
<Virtualize Items="GroupedOrders" Context="orderGroup">
<div style="display: flex; flex-direction: row; flex-wrap: wrap; ">
@foreach (var order in orderGroup)
{
<div style="width: 100px; height: 100px; background-color: cadetblue; padding: 10px; margin: 10px;">
<div>$ @order.Value</div>
</div>
}
</div>
</Virtualize>
}
</div>
<p>元素宽度: @elementWidth px 每行分配 @itemsPerRow 个元素</p>
@code {
private int elementWidth;
int itemsPerRow = 3;
int itemsHeight = 100;
public record Order(Guid Id, int Value);
public IList<Order> Orders { get; set; } = new List<Order>();
public IList<IEnumerable<Order>>? GroupedOrders { get; set; }
[Inject]
[System.Diagnostics.CodeAnalysis.NotNull]
private IJSRuntime? JSRuntime { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
elementWidth = await JSRuntime.InvokeAsync<int>("getElementWidth", "div-test");
itemsPerRow = elementWidth / (itemsHeight+20);
GroupedOrders = Orders
.Select((order, index) => new { order, index })
.GroupBy(x => x.index / itemsPerRow)
.Select(g => g.Select(x => x.order))
.ToList();
StateHasChanged();
}
}
protected override void OnInitialized()
{
var random = new Random();
for (int i = 0; i < 100; i++)
{
Orders.Add(new Order(Guid.NewGuid(), random.Next(20, 9999)));
}
}
}
监控元素的宽度变化动态计算
监控 id="div-test" 元素的宽度变化
标签:elementWidth,flex,index,int,Orders,wrap,new,Blazor,order From: https://www.cnblogs.com/densen2014/p/18677521