Created
August 17, 2019 20:34
-
-
Save vjdw/40b22a64507a6694e8653d06b8655056 to your computer and use it in GitHub Desktop.
ASP.NET Core Blazor VirtualList
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- To be added to _Host.cshtml --> | |
<script> | |
window.blazorHelpers = { | |
getScrollTop : function (element) { | |
return element.scrollTop; | |
}, | |
setScrollTop : function (element, value) { | |
element.scrollTop = value; | |
return element.scrollTop; | |
} | |
} | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@typeparam TItem | |
@inject IJSRuntime JSRuntime | |
<div @ref="scrollContainer" @ref:suppressField style="height: 300px; position: relative; overflow: auto;" @onscroll="HandleScroll"> | |
<div style="height: @(rowHeight*Items.Count())px; width: 1px; position: absolute; top: 0; left: 0;"></div> | |
@foreach (var virtualRow in VirtualRows) | |
{ | |
<div style="height: 150px; width: 30px; background-color: gray; position: absolute; top: @(virtualRow.Top)px; left: 0;">@RowTemplate(virtualRow.Item)</div> | |
} | |
</div> | |
<p>@x scrollTop: @currentCount</p> | |
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button> | |
@code { | |
class VirtualRow | |
{ | |
int rowHeight = 150; | |
public TItem Item { get; set; } | |
public int Index { get; set; } | |
public int Top => Index * rowHeight; | |
} | |
IList<VirtualRow> VirtualRows = new List<VirtualRow>(); | |
[Parameter] | |
public RenderFragment<TItem> RowTemplate { get; set; } | |
[Parameter] | |
public IList<TItem> Items { get; set; } | |
ElementReference scrollContainer; | |
int currentCount = 0; | |
int virtualRowCount = 10; | |
int virtualRowOffset = 0; | |
int rowHeight = 150; | |
protected override void OnParametersSet() | |
{ | |
for (int i = 0; i < virtualRowCount; i++) | |
{ | |
VirtualRows.Add(new VirtualRow {Item = Items[i], Index = i}); | |
} | |
} | |
async Task IncrementCount() | |
{ | |
currentCount+=10; | |
await JSRuntime.InvokeAsync<int>("blazorHelpers.setScrollTop", scrollContainer, currentCount); | |
} | |
async Task HandleScroll(UIEventArgs args) | |
{ | |
var scrollTop = await JSRuntime.InvokeAsync<int>("blazorHelpers.getScrollTop", scrollContainer); | |
currentCount = scrollTop; | |
if (VirtualRows.First().Top < scrollTop) | |
{ | |
virtualRowOffset++; | |
for (int i = 0; i < VirtualRows.Count() - 1; i++) | |
{ | |
VirtualRows[i] = VirtualRows[i+1]; | |
} | |
int j = VirtualRows.Count() - 1; | |
int itemsOffset = virtualRowOffset + j; | |
VirtualRows[j] = new VirtualRow {Item = Items[itemsOffset], Index = itemsOffset}; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment