diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 127de31f7ef..aa82b7cd133 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@  - 10.2.3 + 10.2.4-beta01 diff --git a/src/BootstrapBlazor/Components/TreeView/TreeView.razor.cs b/src/BootstrapBlazor/Components/TreeView/TreeView.razor.cs index fc53cea7ac3..2b13f09d4f4 100644 --- a/src/BootstrapBlazor/Components/TreeView/TreeView.razor.cs +++ b/src/BootstrapBlazor/Components/TreeView/TreeView.razor.cs @@ -245,6 +245,13 @@ public partial class TreeView : IModelEqualityComparer [Parameter] public bool EnableKeyboard { get; set; } + /// + /// 获得/设置 是否将 active 选中节点自动滚动到可视状态 + /// Gets or sets whether to automatically scroll the active selected node into the visible state. + /// + [Parameter] + public bool IsAutoScrollIntoView { get; set; } + /// /// 获得/设置 键盘导航时的滚动至视图选项,默认为 null,使用 { behavior: "smooth", block: "nearest", inline: "start" } /// Gets or sets the scroll into view options for keyboard navigation. Default is null, using { behavior: "smooth", block: "nearest", inline: "start" } @@ -350,6 +357,7 @@ public partial class TreeView : IModelEqualityComparer private string? _searchText; private bool _shouldRender = true; private bool _init; + private bool _scrollIntoView = false; /// /// @@ -410,6 +418,7 @@ protected override async Task OnParametersSetAsync() _activeItem ??= Items.FirstOrDefaultActiveItem(); _activeItem?.SetParentExpand, TItem>(true); _init = true; + _scrollIntoView = true; } } } @@ -424,6 +433,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (_keyboardArrowUpDownTrigger) { + _scrollIntoView = false; _keyboardArrowUpDownTrigger = false; await InvokeVoidAsync("scroll", Id, ScrollIntoViewOptions); } @@ -432,6 +442,12 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { await InvokeVoidAsync("resetTreeViewRow", Id); } + + if (IsAutoScrollIntoView && _scrollIntoView) + { + _scrollIntoView = false; + await InvokeVoidAsync("scroll", Id, ScrollIntoViewOptions); + } } /// @@ -703,6 +719,7 @@ public void SetActiveItem(TreeViewItem? item) { _activeItem = item; _activeItem?.SetParentExpand, TItem>(true); + _scrollIntoView = true; StateHasChanged(); } diff --git a/test/UnitTest/Components/TreeViewTest.cs b/test/UnitTest/Components/TreeViewTest.cs index 9aff84ebb02..a7be5b16cb7 100644 --- a/test/UnitTest/Components/TreeViewTest.cs +++ b/test/UnitTest/Components/TreeViewTest.cs @@ -1269,6 +1269,36 @@ public async Task AllowDrag_Ok() Assert.False(treeDragContext.IsChildren); } + [Fact] + public async Task IsAutoScrollIntoView_Ok() + { + var items = TreeFoo.GetTreeItems(); + ScrollIntoViewOptions? options = null; + Context.JSInterop.SetupVoid("scroll", invocationMatcher => + { + options = invocationMatcher.Arguments[1] as ScrollIntoViewOptions; + return true; + }).SetVoidResult(); + var cut = Context.Render>(pb => + { + pb.Add(a => a.Items, items); + pb.Add(a => a.IsAutoScrollIntoView, true); + }); + Assert.Null(options); + + cut.Render(pb => + { + pb.Add(a => a.ScrollIntoViewOptions, new ScrollIntoViewOptions() + { + Behavior = ScrollIntoViewBehavior.Smooth, + Inline = ScrollIntoViewInline.Center, + Block = ScrollIntoViewBlock.Center + }); + }); + await cut.InvokeAsync(() => cut.Instance.SetActiveItem(items.First())); + Assert.NotNull(options); + } + class MockTree : TreeView where TItem : class { public bool TestComparerItem(TItem? a, TItem? b) => base.Equals(a, b);