From f4071a85d1620f16dd1ff1765c256757e0343d7d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 14:17:11 +0800 Subject: [PATCH 01/52] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=20Partial?= =?UTF-8?q?=20=E6=B8=B2=E6=9F=93=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewRenderMode.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs index 6469a958..40d25778 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs @@ -21,11 +21,5 @@ public enum DockViewRenderMode /// 始终渲染 /// Always render /// - Always, - - /// - /// 部分渲染 可见版面渲染 不可见版面异步渲染 - /// - /// - Partial + Always } From dba799fb6e1f87fb0e2625abebb54e4a412cf679 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 15:08:56 +0800 Subject: [PATCH 02/52] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20DockViewComp?= =?UTF-8?q?onentState=20=E7=B1=BB=E8=AE=B0=E5=BD=95=E5=90=84=E4=B8=AA?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewRenderMode.cs | 12 +-- .../Components/DockViewV2.razor.cs | 76 ++++++++++++++----- .../Components/DockViewV2.razor.js | 2 +- .../Data/DockViewComponentState.cs | 26 +++++++ 4 files changed, 88 insertions(+), 28 deletions(-) create mode 100644 src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs index 40d25778..f1af9a96 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs @@ -12,14 +12,14 @@ namespace BootstrapBlazor.Components; public enum DockViewRenderMode { /// - /// 可见时渲染 - /// Render when visible + /// 始终渲染 + /// Always render /// - OnlyWhenVisible, + Always, /// - /// 始终渲染 - /// Always render + /// 可见时渲染 + /// Render when visible /// - Always + OnlyWhenVisible } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 6130b6e0..f8aa23b4 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Configuration; +using System.Collections.Concurrent; namespace BootstrapBlazor.Components; @@ -169,6 +170,11 @@ public partial class DockViewV2 : IDisposable [NotNull] private DockViewOptions? _options = null; + /// + /// 组件状态集合 + /// + internal ConcurrentDictionary ComponentStates { get; set; } = []; + /// /// /// @@ -274,11 +280,57 @@ public async Task InitializedCallbackAsync() /// Tab close callback method called by JavaScript /// [JSInvokable] - public async Task PanelVisibleChangedCallbackAsync(string title, bool status) + public async Task PanelVisibleChangedCallbackAsync(string key, bool status) { + // 同步更新组件可见状态 + ComponentStates.AddOrUpdate(key, key => + { + return new DockViewComponentState() + { + Key = key, + Visible = status + }; + }, (key, v) => + { + v.Visible = status; + return v; + }); + + // 通知订阅者 if (OnVisibleStateChangedAsync != null) { - await OnVisibleStateChangedAsync(title, status); + await OnVisibleStateChangedAsync(key, status); + } + } + + /// + /// 锁定回调方法 由 JavaScript 调用 + /// Lock callback method called by JavaScript + /// + [JSInvokable] + public async Task LockChangedCallbackAsync(string[] panels, bool state) + { + // 同步更新组件锁定状态 + foreach (var panel in panels) + { + ComponentStates.AddOrUpdate(panel, key => + { + return new DockViewComponentState() + { + Key = key, + IsLock = state + }; + }, (key, v) => + { + v.IsLock = state; + return v; + }); + } + + // 通知订阅者 + if (OnLockChangedCallbackAsync != null) + { + await OnLockChangedCallbackAsync(panels, state); } } @@ -293,11 +345,7 @@ public async Task PanelVisibleChangedCallbackAsync(string title, bool status) public Task LoadTabs(List tabs) { // 客户端请求渲染当前激活的标签 - _loadTabs.Clear(); - foreach (var tab in tabs) - { - _loadTabs.Add(tab); - } + _loadTabs = tabs.ToHashSet(); StateHasChanged(); return Task.CompletedTask; @@ -310,7 +358,6 @@ public Task LoadTabs(List tabs) /// public bool ShowTab(string? key) { - // TODO: Partial 模式下使用临时回滚稍后完善 if (Renderer == DockViewRenderMode.Always) { return true; @@ -319,19 +366,6 @@ public bool ShowTab(string? key) return _loadTabs.Contains(key ?? string.Empty); } - /// - /// 锁定回调方法 由 JavaScript 调用 - /// Lock callback method called by JavaScript - /// - [JSInvokable] - public async Task LockChangedCallbackAsync(string[] panels, bool state) - { - if (OnLockChangedCallbackAsync != null) - { - await OnLockChangedCallbackAsync(panels, state); - } - } - /// /// 分割器回调方法 由 JavaScript 调用 /// Splitter callback method called by JavaScript diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js index e6d04dab..eed527ae 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js @@ -33,7 +33,7 @@ export async function init(id, invoke, options) { invoke.invokeMethodAsync(options.splitterCallback); }); dockview.on('loadTabs', tabs => { - + invoke.invokeMethodAsync(options.loadTabs, tabs); }); EventHandler.on(document, 'changed.bb.theme', updateTheme); diff --git a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs new file mode 100644 index 00000000..11eab00f --- /dev/null +++ b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs @@ -0,0 +1,26 @@ +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone + +namespace BootstrapBlazor.Components; + +/// +/// DockView 组件状态持久化类 +/// +record struct DockViewComponentState +{ + /// + /// 获得/设置 组件唯一标识值 默认 null 未设置 + /// + public string? Key { get; set; } + + /// + /// 获得/设置 组件是否锁定 默认 false + /// + public bool IsLock { get; set; } + + /// + /// 获得/设置 组件是否可见 默认 false + /// + public bool Visible { get; set; } +} From d29a292a097c18467048bac19277ed37aae75cab Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 15:14:21 +0800 Subject: [PATCH 03/52] =?UTF-8?q?refactor:=20=E5=AE=9E=E7=8E=B0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=8A=B6=E6=80=81=E5=90=8C=E6=AD=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index bfc7563a..8bad30c4 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ @@ -133,6 +133,15 @@ public partial class DockViewComponent [JsonIgnore] public Func? OnClickTitleBarCallback { get; set; } + /// + /// 获得/设置 DockContent 实例 + /// Gets or sets the DockContent instance. + /// + [CascadingParameter] + [NotNull] + [JsonIgnore] + private DockViewV2? DockView { get; set; } + /// /// /// @@ -143,6 +152,21 @@ protected override void OnInitialized() Type = DockViewContentType.Component; } + /// + /// + /// + protected override void OnParametersSet() + { + base.OnParametersSet(); + + // 根据容器状态同步组件状态 + if (!string.IsNullOrEmpty(Key) && DockView.ComponentStates.TryGetValue(Key, out var state)) + { + IsLock = state.IsLock; + Visible = state.Visible; + } + } + private async Task OnClickBar() { if (OnClickTitleBarCallback != null) From 6b6c57d0c0e5b55ecff071606bf520d68cbcfa99 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Fri, 10 Apr 2026 15:16:11 +0800 Subject: [PATCH 04/52] =?UTF-8?q?refactor:=20=E4=BF=AE=E6=94=B9panelVisibl?= =?UTF-8?q?eChangedCallback=E5=8F=82=E6=95=B0=E6=94=B9=E4=B8=BA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewV2.razor.js | 4 ++-- .../wwwroot/js/dockview-extensions.js | 2 +- .../wwwroot/js/dockview-group.js | 4 ++-- .../wwwroot/js/dockview-panel.js | 2 +- .../wwwroot/js/dockview-utils.js | 14 +++----------- 5 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js index eed527ae..8df2b141 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js @@ -26,8 +26,8 @@ export async function init(id, invoke, options) { dockview.on('lockChanged', ({ title, isLock }) => { invoke.invokeMethodAsync(options.lockChangedCallback, title, isLock); }); - dockview.on('panelVisibleChanged', ({ title, status }) => { - invoke.invokeMethodAsync(options.panelVisibleChangedCallback, title, status); + dockview.on('panelVisibleChanged', ({ key, status }) => { + invoke.invokeMethodAsync(options.panelVisibleChangedCallback, key, status); }); dockview.on('groupSizeChanged', () => { invoke.invokeMethodAsync(options.splitterCallback); diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index 367b8cac..97d7a17a 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -76,7 +76,7 @@ DockviewComponent.prototype.removePanel = function (...args) { if (!panel.group.locked) { removePanel.apply(this, args) if (!this.isClearing) { - this._panelVisibleChanged?.fire({ title: panel.title, status: false }); + this._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); } } } diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js index eb3e1e8b..21f13c06 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js @@ -99,7 +99,7 @@ const addPanelWidthGroupId = (dockview, panel, index) => { position: { referenceGroup: group, index: index || 0 }, params: { ...panel.params, rect, packup, visible: true } }) - dockview._panelVisibleChanged?.fire({ title: panel.title, status: true }); + dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); } const addPanelWidthCreatGroup = (dockview, panel, panels) => { @@ -138,7 +138,7 @@ const addPanelWidthCreatGroup = (dockview, panel, panels) => { } if (direction) option.position.direction = direction dockview.addPanel(option); - dockview._panelVisibleChanged?.fire({ title: panel.title, status: true }); + dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); } const getOrientation = function (child, group) { diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js index ec37daa6..e4b13270 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js @@ -84,7 +84,7 @@ const onRemovePanel = event => { event.view.content.element.append(event.titleMenuEle) } if (dockview.params.template) { - // dockview.params.template.append(event.view.content.element) + dockview.params.template.append(event.view.content.element) } } } diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index ca95a21c..7ddf178f 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -97,23 +97,15 @@ const initDockview = (dockview, options, template) => { if (!visible) { dockview.removePanel(panel) } - dockview._panelVisibleChanged?.fire({ title: panel.title, status: visible }); + dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: visible }); }) delPanels.forEach(panel => { - dockview._panelVisibleChanged?.fire({ title: panel.title, status: false }); + dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); }) - if (options.renderer === 'always') { - - } - else if (options.renderer === 'partial' || options.renderer === 'onlyWhenVisible') { + if (options.renderer === 'onlyWhenVisible') { const visiblePanels = groups.filter(g => g.isVisible).map(g => g.panels.find(p => p.params.isActive) || g.panels.find(p => p.api.isVisible)) dockview._loadTabs?.fire(visiblePanels.filter(p => Boolean(p)).map(p => p.params.key)); } - if (options.renderer === 'partial') { - if (dockview.panels.length > 0) { - dockview._loadTabs?.fire(dockview.panels.map(p => p.params.key)); - } - } const { floatingGroups } = dockview.params dockview.floatingGroups.forEach(fg => { const { top, right, bottom, left } = floatingGroups.find(g => g.data.id == fg.group.id).position From 3f61fbf93440cba77ede604e6cfd5821b90a207f Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 15:28:46 +0800 Subject: [PATCH 05/52] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=80=BC=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 7 +++++- .../Components/DockViewV2.razor.cs | 24 +++++++------------ .../Data/DockViewComponentState.cs | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 8bad30c4..a46090ec 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -160,8 +160,13 @@ protected override void OnParametersSet() base.OnParametersSet(); // 根据容器状态同步组件状态 - if (!string.IsNullOrEmpty(Key) && DockView.ComponentStates.TryGetValue(Key, out var state)) + if (!string.IsNullOrEmpty(Key)) { + var state = DockView.ComponentStates.GetOrAdd(Key, key => new DockViewComponentState + { + IsLock = IsLock, + Visible = Visible + }); IsLock = state.IsLock; Visible = state.Visible; } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index f8aa23b4..151bf4c8 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -344,26 +344,20 @@ public async Task LockChangedCallbackAsync(string[] panels, bool state) [JSInvokable] public Task LoadTabs(List tabs) { - // 客户端请求渲染当前激活的标签 _loadTabs = tabs.ToHashSet(); - StateHasChanged(); - return Task.CompletedTask; - } - - /// - /// 检查指定 Key 值 DockviewComponent 是否处于激活状态 - /// Checks whether the DockviewComponent with the specified key is active. - /// - /// - public bool ShowTab(string? key) - { - if (Renderer == DockViewRenderMode.Always) + bool rendered = false; + foreach (var key in ComponentStates.Keys) { - return true; + var state = ComponentStates[key]; + state.Visible = _loadTabs.Contains(key); } - return _loadTabs.Contains(key ?? string.Empty); + if (rendered) + { + StateHasChanged(); + } + return Task.CompletedTask; } /// diff --git a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs index 11eab00f..9c8f961f 100644 --- a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs +++ b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs @@ -17,7 +17,7 @@ record struct DockViewComponentState /// /// 获得/设置 组件是否锁定 默认 false /// - public bool IsLock { get; set; } + public bool? IsLock { get; set; } /// /// 获得/设置 组件是否可见 默认 false From 086ac3e4b5cc3c18114a5cd4e80313aa693903b1 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 15:55:54 +0800 Subject: [PATCH 06/52] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20Render=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor | 2 +- .../Components/DockViewComponent.razor.cs | 7 ++++++- .../Components/DockViewV2.razor.cs | 8 +++++++- .../Data/DockViewComponentState.cs | 7 ++++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor index c6500815..3724dec0 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor @@ -11,7 +11,7 @@ { } - @if (Visible) + @if (_rendered) { @ChildContent } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index a46090ec..ef64c0c9 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -142,6 +142,8 @@ public partial class DockViewComponent [JsonIgnore] private DockViewV2? DockView { get; set; } + private bool _rendered = false; + /// /// /// @@ -164,11 +166,14 @@ protected override void OnParametersSet() { var state = DockView.ComponentStates.GetOrAdd(Key, key => new DockViewComponentState { + Key = key, IsLock = IsLock, - Visible = Visible + Visible = Visible, + Render = _rendered }); IsLock = state.IsLock; Visible = state.Visible; + _rendered = state.Render; } } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 151bf4c8..6929d7b6 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -350,7 +350,13 @@ public Task LoadTabs(List tabs) foreach (var key in ComponentStates.Keys) { var state = ComponentStates[key]; - state.Visible = _loadTabs.Contains(key); + + var render = _loadTabs.Contains(key); + if (render != state.Render) + { + state.Render = render; + rendered = true; + } } if (rendered) diff --git a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs index 9c8f961f..e855316e 100644 --- a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs +++ b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs @@ -7,7 +7,7 @@ namespace BootstrapBlazor.Components; /// /// DockView 组件状态持久化类 /// -record struct DockViewComponentState +class DockViewComponentState { /// /// 获得/设置 组件唯一标识值 默认 null 未设置 @@ -23,4 +23,9 @@ record struct DockViewComponentState /// 获得/设置 组件是否可见 默认 false /// public bool Visible { get; set; } + + /// + /// 获得/设置 组件是否渲染 默认 false + /// + public bool Render { get; set; } } From 5828562dcb52157ac8fc4647e24e9b01d542fcd3 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 15:56:22 +0800 Subject: [PATCH 07/52] =?UTF-8?q?refactor:=20=E6=81=A2=E5=A4=8D=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewRenderMode.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs index f1af9a96..40d25778 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewRenderMode.cs @@ -12,14 +12,14 @@ namespace BootstrapBlazor.Components; public enum DockViewRenderMode { /// - /// 始终渲染 - /// Always render + /// 可见时渲染 + /// Render when visible /// - Always, + OnlyWhenVisible, /// - /// 可见时渲染 - /// Render when visible + /// 始终渲染 + /// Always render /// - OnlyWhenVisible + Always } From 4f5f3d9e0e5c74a72efa0d61144d54524356b498 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Fri, 10 Apr 2026 16:33:54 +0800 Subject: [PATCH 08/52] =?UTF-8?q?refactor=EF=BC=9A=E5=A2=9E=E5=8A=A0enable?= =?UTF-8?q?LocalStorage=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wwwroot/js/dockview-utils.js | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index 7ddf178f..060aa9f9 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -6,6 +6,7 @@ import { getConfig, reloadFromConfig, loadPanelsFromLocalstorage, saveConfig } f import './dockview-extensions.js' const cerateDockview = (el, options) => { + options.enableLocalStorage = true; const theme = options.theme || "dockview-theme-light"; const template = el.querySelector('template'); options.renderer ??= 'onlyWhenVisible'; // onlyWhenVisible | partial | always @@ -92,16 +93,19 @@ const initDockview = (dockview, options, template) => { const delPanelsStr = localStorage.getItem(dockview.params.options.localStorageKey + '-panels'); const delPanels = delPanelsStr && JSON.parse(delPanelsStr) || []; - panels.forEach(panel => { - const visible = panel.params.visible - if (!visible) { - dockview.removePanel(panel) - } - dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: visible }); - }) - delPanels.forEach(panel => { - dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); - }) + if (options.enableLocalStorage) { + panels.forEach(panel => { + const visible = panel.params.visible + if (!visible) { + dockview.removePanel(panel) + } + dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: visible }); + }) + delPanels.forEach(panel => { + dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); + }) + } + if (options.renderer === 'onlyWhenVisible') { const visiblePanels = groups.filter(g => g.isVisible).map(g => g.panels.find(p => p.params.isActive) || g.panels.find(p => p.api.isVisible)) dockview._loadTabs?.fire(visiblePanels.filter(p => Boolean(p)).map(p => p.params.key)); From 8602c8a025dec3a8cc83bd875d41e93510967584 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 16:50:16 +0800 Subject: [PATCH 09/52] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=88=87=E6=8D=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index ef64c0c9..79760fac 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -171,8 +171,16 @@ protected override void OnParametersSet() Visible = Visible, Render = _rendered }); - IsLock = state.IsLock; - Visible = state.Visible; + + if (state.Visible != Visible) + { + state.Visible = Visible; + } + if (state.IsLock != IsLock) + { + state.IsLock = IsLock; + } + _rendered = state.Render; } } From e2da3b10d23c7df3477b9bcdf11a4ca1188d12ec Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 16:59:52 +0800 Subject: [PATCH 10/52] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 70 ++++++----- .../Components/DockViewComponentBase.cs | 33 +++--- .../Components/DockViewConfig.cs | 78 +++++++------ .../Components/DockViewContent.cs | 4 +- .../Components/DockViewDropdownIcon.razor.cs | 4 - .../Components/DockViewIcon.razor.cs | 11 +- .../Components/DockViewOptions.cs | 12 +- .../Components/DockViewTitleBar.razor.cs | 12 +- .../Components/DockViewV2.razor.cs | 110 +++++++++--------- .../Converters/DockViewComponentConverter.cs | 3 +- .../Data/DockViewComponentState.cs | 15 ++- 11 files changed, 181 insertions(+), 171 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 79760fac..b08e9f10 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -8,135 +8,149 @@ namespace BootstrapBlazor.Components; /// -/// DockContentItem 配置项子项对标 content 配置项内部 content 配置 +/// DockView 组件配置项,对应 content 配置项中的组件项 +/// DockView component option corresponding to a component item in the content configuration /// public partial class DockViewComponent { /// - /// 获得/设置 组件是否显示 Header 默认 true 显示 + /// 获得/设置 组件是否显示标题栏,默认为 true + /// Gets or sets whether the component header is displayed. Default is true /// [Parameter] public bool ShowHeader { get; set; } = true; /// - /// 获得/设置 组件 Title + /// 获得/设置 组件标题 + /// Gets or sets the component title /// [Parameter] public string? Title { get; set; } /// - /// 获得/设置 组件 Title 宽度 默认 null 未设置 + /// 获得/设置 组件标题宽度,默认为 null + /// Gets or sets the component title width. Default is null /// [Parameter] public int? TitleWidth { get; set; } /// - /// 获得/设置 组件 Title 样式 默认 null 未设置 + /// 获得/设置 组件标题样式类,默认为 null + /// Gets or sets the component title CSS class. Default is null /// [Parameter] public string? TitleClass { get; set; } /// - /// 获得/设置 Title 模板 默认 null 未设置 + /// 获得/设置 标题模板,默认为 null + /// Gets or sets the title template. Default is null /// [Parameter] [JsonIgnore] public RenderFragment? TitleTemplate { get; set; } /// - /// 获得/设置 组件 Class 默认 null 未设置 + /// 获得/设置 组件样式类,默认为 null + /// Gets or sets the component CSS class. Default is null /// [Parameter] public string? Class { get; set; } /// - /// 获得/设置 组件是否可见 默认 true 可见 + /// 获得/设置 组件是否可见,默认为 true + /// Gets or sets whether the component is visible. Default is true /// [Parameter] public bool Visible { get; set; } = true; /// - /// 获得/设置 组件是否允许关闭 默认 null 使用 DockView 的配置 + /// 获得/设置 组件是否允许关闭,默认为 null,未设置时使用 DockView 的配置 + /// Gets or sets whether the component can be closed. Default is null. When not set, the DockView configuration is used /// [Parameter] public bool? ShowClose { get; set; } /// - /// 获得/设置 组件唯一标识值 默认 null 未设置时取 Title 作为唯一标识 + /// 获得/设置 组件唯一标识,默认为 null,未设置时使用 Title 作为唯一标识 + /// Gets or sets the unique component identifier. Default is null. When not set, Title is used as the unique identifier /// [Parameter] public string? Key { get; set; } /// - /// 获得/设置 是否锁定 默认 null 未设置时取 DockView 的配置 + /// 获得/设置 组件是否锁定,默认为 null,未设置时使用 DockView 的配置 + /// Gets or sets whether the component is locked. Default is null. When not set, the DockView configuration is used /// - /// 锁定后无法拖动 [Parameter] public bool? IsLock { get; set; } /// - /// 获得/设置 是否显示锁定按钮 默认 null 未设置时取 DockView 的配置 + /// 获得/设置 是否显示锁定按钮,默认为 null,未设置时使用 DockView 的配置 + /// Gets or sets whether the lock button is displayed. Default is null. When not set, the DockView configuration is used /// [Parameter] public bool? ShowLock { get; set; } /// - /// 获得/设置 是否悬浮 默认 null 未设置时取 DockView 的配置 + /// 获得/设置 是否悬浮,默认为 null,未设置时使用 DockView 的配置 + /// Gets or sets whether the component is floating. Default is null. When not set, the DockView configuration is used /// [Parameter] public bool? IsFloating { get; set; } /// - /// 获得/设置 是否显示可悬浮按钮 默认 null 未设置时取 DockView 的配置 + /// 获得/设置 是否显示悬浮按钮,默认为 null,未设置时使用 DockView 的配置 + /// Gets or sets whether the float button is displayed. Default is null. When not set, the DockView configuration is used /// [Parameter] public bool? ShowFloat { get; set; } /// - /// 获得/设置 是否显示最大化按钮 默认 null 未设置时取 DockView 的配置 + /// 获得/设置 是否显示最大化按钮,默认为 null,未设置时使用 DockView 的配置 + /// Gets or sets whether the maximize button is displayed. Default is null. When not set, the DockView configuration is used /// [Parameter] public bool? ShowMaximize { get; set; } /// - /// 获得/设置 是否一直显示 默认 null 未设置时取 DockView 的配置 + /// 获得/设置 组件渲染模式,默认为 null,未设置时使用 DockView 的配置 + /// Gets or sets the component render mode. Default is null. When not set, the DockView configuration is used /// [Parameter] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Renderer { get; set; } /// - /// 获得/设置 是否显示标题前置图标 默认 false 不显示 + /// 获得/设置 是否显示标题前置图标,默认为 false + /// Gets or sets whether the leading title icon is displayed. Default is false /// [Parameter] [JsonIgnore] public bool ShowTitleBar { get; set; } /// - /// 获得/设置 标题前置图标 默认 null 未设置使用默认图标 + /// 获得/设置 标题前置图标,默认为 null,未设置时使用默认图标 + /// Gets or sets the leading title icon. Default is null. When not set, the default icon is used /// [Parameter] [JsonIgnore] public string? TitleBarIcon { get; set; } /// - /// 获得/设置 标题前置图标 Url 默认 null 未设置使用默认图标 + /// 获得/设置 标题前置图标地址,默认为 null,未设置时使用默认图标 + /// Gets or sets the leading title icon URL. Default is null. When not set, the default icon is used /// [Parameter] [JsonIgnore] public string? TitleBarIconUrl { get; set; } /// - /// 获得/设置 标题前置图标点击回调方法 默认 null + /// 获得/设置 标题前置图标点击回调方法,默认为 null + /// Gets or sets the click callback for the leading title icon. Default is null /// [Parameter] [JsonIgnore] public Func? OnClickTitleBarCallback { get; set; } - - /// - /// 获得/设置 DockContent 实例 - /// Gets or sets the DockContent instance. - /// [CascadingParameter] [NotNull] [JsonIgnore] @@ -194,9 +208,9 @@ private async Task OnClickBar() } /// - /// 设置 Visible 参数方法 + /// 设置组件可见状态 + /// Sets the component visibility /// - /// public void SetVisible(bool visible) { Visible = visible; diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs index f98d1e9b..b2073a01 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs @@ -8,44 +8,39 @@ namespace BootstrapBlazor.Components; /// -/// DockComponent 基类 -/// Base class for DockComponent +/// DockView 组件基类 +/// Base class for DockView components /// public abstract class DockViewComponentBase : IdComponentBase, IDisposable { /// - /// 获得/设置 渲染类型 默认 Component - /// Gets or sets the render type. Default is Component. + /// 获得/设置 组件渲染类型,默认为 Component + /// Gets or sets the component render type. Default is Component /// [Parameter] public DockViewContentType Type { get; set; } /// - /// 获得/设置 组件宽度百分比 默认 null 未设置 - /// Gets or sets the component width percentage. Default is null (not set). + /// 获得/设置 组件宽度百分比,默认为 null + /// Gets or sets the component width percentage. Default is null /// [Parameter] public int? Width { get; set; } /// - /// 获得/设置 组件高度百分比 默认 null 未设置 - /// Gets or sets the component height percentage. Default is null (not set). + /// 获得/设置 组件高度百分比,默认为 null + /// Gets or sets the component height percentage. Default is null /// [Parameter] public int? Height { get; set; } /// - /// 获得/设置 子组件 - /// Gets or sets the child content. + /// 获得/设置 子组件内容 + /// Gets or sets the child content /// [Parameter] [JsonIgnore] public RenderFragment? ChildContent { get; set; } - - /// - /// 获得/设置 DockContent 实例 - /// Gets or sets the DockContent instance. - /// [CascadingParameter] private List? Parent { get; set; } @@ -60,8 +55,8 @@ protected override void OnInitialized() } /// - /// 资源销毁方法 - /// Resource disposal method + /// 资源释放方法 + /// Releases resources /// /// protected virtual void Dispose(bool disposing) @@ -73,8 +68,8 @@ protected virtual void Dispose(bool disposing) } /// - /// 资源销毁方法 - /// Resource disposal method + /// 资源释放方法 + /// Releases resources /// public void Dispose() { diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs index 963fc419..4605efd7 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs @@ -6,119 +6,121 @@ namespace BootstrapBlazor.Components; +/// +/// DockView 配置项 +/// DockView configuration options +/// class DockViewConfig { /// - /// 获得/设置 是否启用本地布局保持 默认 true - /// Gets or sets whether to enable local layout persistence. Default is true. + /// 获得/设置 是否启用本地布局持久化,默认为 true + /// Gets or sets whether local layout persistence is enabled. Default is true /// public bool EnableLocalStorage { get; set; } = true; /// - /// 获得/设置 是否锁定 默认 false - /// Gets or sets whether the component is locked. Default is false. + /// 获得/设置 是否锁定,默认为 false + /// Gets or sets whether the component is locked. Default is false /// - /// 锁定后无法拖动 [JsonPropertyName("lock")] public bool IsLock { get; set; } /// - /// 获得/设置 是否显示锁定按钮 默认 true 显示 - /// Gets or sets whether the lock button is displayed. Default is true. + /// 获得/设置 是否显示锁定按钮,默认为 true + /// Gets or sets whether the lock button is displayed. Default is true /// public bool ShowLock { get; set; } /// - /// 获得/设置 是否悬浮 默认 false - /// Gets or sets whether the component is floating. Default is false. + /// 获得/设置 是否悬浮,默认为 false + /// Gets or sets whether the component is floating. Default is false /// - /// 锁定后无法拖动 public bool IsFloating { get; set; } /// - /// 获得/设置 是否显示可悬浮按钮 默认 true - /// Gets or sets whether the float button is displayed. Default is true. + /// 获得/设置 是否显示悬浮按钮,默认为 true + /// Gets or sets whether the float button is displayed. Default is true /// public bool ShowFloat { get; set; } = true; /// - /// 获得/设置 是否显示关闭按钮 默认 true 显示 - /// Gets or sets whether the close button is displayed. Default is true. + /// 获得/设置 是否显示关闭按钮,默认为 true + /// Gets or sets whether the close button is displayed. Default is true /// public bool ShowClose { get; set; } /// - /// 获得/设置 是否显示图钉按钮 默认 true - /// Gets or sets whether the pin button is displayed. Default is true. + /// 获得/设置 是否显示图钉按钮,默认为 true + /// Gets or sets whether the pin button is displayed. Default is true /// public bool ShowPin { get; set; } = true; /// - /// 获得/设置 是否显示最大化按钮 默认 true - /// Gets or sets whether the maximize button is displayed. Default is true. + /// 获得/设置 是否显示最大化按钮,默认为 true + /// Gets or sets whether the maximize button is displayed. Default is true /// public bool ShowMaximize { get; set; } = true; /// - /// 获得/设置 客户端渲染模式 默认 null 客户端默认使用 always onlyWhenVisible 值 - /// Gets or sets the client render mode. Default is null, the client will use always onlyWhenVisible value. + /// 获得/设置 客户端渲染模式 + /// Gets or sets the client render mode /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public DockViewRenderMode Renderer { get; set; } /// - /// 获得/设置 标签页可见状态改变事件回调 - /// Gets or sets the callback for when the tab visibility changes. + /// 获得/设置 标签页可见状态变更回调名称 + /// Gets or sets the callback name for tab visibility state changes /// public string? PanelVisibleChangedCallback { get; set; } /// - /// 获得/设置 组件初始化完成事件回调 - /// Gets or sets the callback for when the component is initialized. + /// 获得/设置 组件初始化完成回调名称 + /// Gets or sets the callback name for component initialization completion /// public string? InitializedCallback { get; set; } /// - /// 获得/设置 锁定事件回调 - /// Gets or sets the callback for when the lock state changes. + /// 获得/设置 锁定状态变更回调名称 + /// Gets or sets the callback name for lock state changes /// public string? LockChangedCallback { get; set; } /// - /// 获得/设置 分割栏调整事件回调 - /// Gets or sets the callback for when the splitter is adjusted. + /// 获得/设置 分割器调整回调名称 + /// Gets or sets the callback name for splitter adjustments /// public string? SplitterCallback { get; set; } /// - /// 获得/设置 加载当前激活标签页事件回调 - /// Gets or sets the callback for loading the currently active tab. + /// 获得/设置 加载标签页回调名称 + /// Gets or sets the callback name for loading tabs /// public string? LoadTabs { get; set; } /// - /// 获得/设置 客户端缓存键值 - /// Gets or sets the client-side cache key. + /// 获得/设置 客户端缓存键 + /// Gets or sets the client-side cache key /// public string? LocalStorageKey { get; set; } /// - /// 获得/设置 配置项集合 默认 空集合 - /// Gets or sets the configuration items. Default is an empty collection. + /// 获得/设置 配置项集合,默认为空集合 + /// Gets or sets the configuration items. Default is an empty collection /// [JsonPropertyName("content")] [JsonConverter(typeof(DockViewComponentConverter))] public List Contents { get; set; } = []; /// - /// 获得/设置 组件主题 默认 null 未设置 - /// Gets or sets the component theme. Default is null, not set. + /// 获得/设置 组件主题,默认为 null + /// Gets or sets the component theme. Default is null /// public string? Theme { get; set; } /// - /// 获得/设置 布局配置 默认 null 未设置 - /// Gets or sets the layout configuration. Default is null, not set. + /// 获得/设置 布局配置,默认为 null + /// Gets or sets the layout configuration. Default is null /// public string? LayoutConfig { get; set; } } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewContent.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewContent.cs index a9842c17..dba516f6 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewContent.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewContent.cs @@ -10,13 +10,13 @@ namespace BootstrapBlazor.Components; /// /// DockContent 类对标 content 配置项 -/// DockContent class corresponds to the content configuration item. +/// DockContent class corresponds to the content configuration item /// public class DockViewContent : DockViewComponentBase { /// /// 获得/设置 子项集合 - /// Gets or sets the collection of child items. + /// Gets or sets the collection of child items /// [JsonConverter(typeof(DockViewComponentConverter))] [JsonPropertyName("content")] diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewDropdownIcon.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewDropdownIcon.razor.cs index 25e388ca..3ccbc53d 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewDropdownIcon.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewDropdownIcon.razor.cs @@ -10,10 +10,6 @@ namespace BootstrapBlazor.Components; /// public partial class DockViewDropdownIcon { - /// - /// 获得 样式字符串 - /// Gets the CSS class string. - /// private string? ClassString => CssBuilder.Default("dropdown dropdown-center bb-dockview-control-icon") .AddClass($"bb-dockview-control-icon-{IconName}") .Build(); diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewIcon.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewIcon.razor.cs index 665c651e..c224c227 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewIcon.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewIcon.razor.cs @@ -15,30 +15,25 @@ public partial class DockViewIcon { /// /// 获得/设置 资源文件接口实例 - /// Gets or sets the resource file interface instance. + /// Gets or sets the resource file interface instance /// [Inject, NotNull] protected IStringLocalizer? Localizer { get; set; } /// /// 获得/设置 图标名称 - /// Gets or sets the icon name. + /// Gets or sets the icon name /// [Parameter, NotNull] [EditorRequired] public string? IconName { get; set; } - - /// - /// 获得 样式字符串 - /// Gets the CSS class string. - /// private string? ClassString => CssBuilder.Default("bb-dockview-control-icon") .AddClass($"bb-dockview-control-icon-{IconName}") .Build(); /// /// 获得 图标地址 - /// Gets the icon URL. + /// Gets the icon URL /// protected string Href => $"./_content/BootstrapBlazor.DockView/icon/dockview.svg#{IconName}"; diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewOptions.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewOptions.cs index 191cd049..5046d00d 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewOptions.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewOptions.cs @@ -5,22 +5,26 @@ namespace BootstrapBlazor.Components; /// -/// DockView 组件配置类 +/// DockView 组件配置项 +/// DockView component options /// class DockViewOptions { /// - /// 获得/设置 组件本地化版本信息 + /// 获得/设置 组件版本信息 + /// Gets or sets the component version information /// public string? Version { get; set; } /// - /// 获得/设置 是否开启本地存储 默认 null 未设置 + /// 获得/设置 是否启用本地存储,默认为 null + /// Gets or sets whether local storage is enabled. Default is null /// public bool? EnableLocalStorage { get; set; } /// - /// 获得/设置 本地存储前缀 默认 bb-dock + /// 获得/设置 本地存储前缀,默认为 bb-dock + /// Gets or sets the local storage prefix. Default is bb-dock /// public string? LocalStoragePrefix { get; set; } } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewTitleBar.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewTitleBar.razor.cs index d6dab5f6..a0f1c9a0 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewTitleBar.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewTitleBar.razor.cs @@ -7,24 +7,28 @@ namespace BootstrapBlazor.Components; /// -/// DockViewTitle 组件 +/// DockView 标题栏组件 +/// DockView title bar component /// public partial class DockViewTitleBar { /// - /// 获得/设置 标题前置图标点击回调方法 默认 null + /// 获得/设置 标题前置图标点击回调方法,默认为 null + /// Gets or sets the click callback for the leading title icon. Default is null /// [Parameter] public Func? OnClickBarCallback { get; set; } /// - /// 获得/设置 标题前置图标 默认 null 未设置使用默认图标 + /// 获得/设置 标题前置图标,默认为 null,未设置时使用默认图标 + /// Gets or sets the leading title icon. Default is null. When not set, the default icon is used /// [Parameter] public string? BarIcon { get; set; } /// - /// 获得/设置 标题前置图标 Url 默认 null 未设置使用默认图标 + /// 获得/设置 标题前置图标地址,默认为 null,未设置时使用默认图标 + /// Gets or sets the leading title icon URL. Default is null. When not set, the default icon is used /// [Parameter] public string? BarIconUrl { get; set; } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 6929d7b6..ceaeeed3 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -9,13 +9,14 @@ namespace BootstrapBlazor.Components; /// -/// DockViewV2 组件 +/// DockViewV2 组件 +/// DockViewV2 component /// public partial class DockViewV2 : IDisposable { /// - /// 获得/设置 DockView 名称 默认 null 用于本地存储识别 - /// Gets or sets the DockView name. Default is null, used for local storage identification. + /// 获得/设置 DockView 名称,默认为 null,用于本地存储标识 + /// Gets or sets the DockView name. Default is null and it is used for local storage identification /// [Parameter] [EditorRequired] @@ -24,128 +25,126 @@ public partial class DockViewV2 : IDisposable /// /// 获得/设置 布局配置 - /// Gets or sets the layout configuration. + /// Gets or sets the layout configuration /// [Parameter] public string? LayoutConfig { get; set; } /// - /// 获得/设置 是否显示关闭按钮 默认为 true - /// Gets or sets whether to show the close button. Default is true. + /// 获得/设置 是否显示关闭按钮,默认为 true + /// Gets or sets whether the close button is displayed. Default is true /// [Parameter] public bool ShowClose { get; set; } = true; /// - /// 获得/设置 是否锁定 默认 false - /// Gets or sets whether to lock. Default is false. + /// 获得/设置 是否锁定,默认为 false + /// Gets or sets whether the component is locked. Default is false /// - /// 锁定后无法拖动 [Parameter] public bool IsLock { get; set; } /// - /// 获得/设置 是否显示锁定按钮 默认 true - /// Gets or sets whether to show the lock button. Default is true. + /// 获得/设置 是否显示锁定按钮,默认为 true + /// Gets or sets whether the lock button is displayed. Default is true /// [Parameter] public bool ShowLock { get; set; } = true; /// - /// 获得/设置 是否显示最大化按钮 默认 true - /// Gets or sets whether to show the maximize button. Default is true. + /// 获得/设置 是否显示最大化按钮,默认为 true + /// Gets or sets whether the maximize button is displayed. Default is true /// [Parameter] public bool ShowMaximize { get; set; } = true; /// - /// 获得/设置 是否悬浮 默认 false - /// Gets or sets whether to float. Default is false. + /// 获得/设置 是否悬浮,默认为 false + /// Gets or sets whether the component is floating. Default is false /// [Parameter] public bool IsFloating { get; set; } /// - /// 获得/设置 是否显示可悬浮按钮 默认 true - /// Gets or sets whether to show the float button. Default is true. + /// 获得/设置 是否显示悬浮按钮,默认为 true + /// Gets or sets whether the float button is displayed. Default is true /// [Parameter] public bool ShowFloat { get; set; } = true; /// - /// 获得/设置 是否显示显示图钉按钮 默认 true - /// Gets or sets whether to show the pin button. Default is true. + /// 获得/设置 是否显示图钉按钮,默认为 true + /// Gets or sets whether the pin button is displayed. Default is true /// [Parameter] public bool ShowPin { get; set; } = true; /// - /// 获得/设置 客户端渲染模式 默认 客户端默认使用 always onlyWhenVisible 值 - /// Gets or sets the client render mode. Default is . The client defaults to using always onlyWhenVisible values. + /// 获得/设置 客户端渲染模式,默认为 + /// Gets or sets the client render mode. Default is /// [Parameter] public DockViewRenderMode Renderer { get; set; } /// - /// 获得/设置 锁定状态回调此方法 - /// Gets or sets the callback method for lock state changes. + /// 获得/设置 锁定状态变更回调方法 + /// Gets or sets the callback for lock state changes /// [Parameter] public Func? OnLockChangedCallbackAsync { get; set; } /// - /// 获得/设置 标签关闭时回调此方法 - /// Gets or sets the callback method for when a tab is closed. + /// 获得/设置 标签页可见状态变更回调方法 + /// Gets or sets the callback for tab visibility state changes /// - /// 可用于第三方组件显示标签页状态更新 [Parameter] public Func? OnVisibleStateChangedAsync { get; set; } /// - /// 获得/设置 标签页调整大小完成时回调此方法 - /// Gets or sets the callback method for when a tab is resized. + /// 获得/设置 标签页调整大小完成回调方法 + /// Gets or sets the callback for when tab resizing is completed /// [Parameter] public Func? OnSplitterCallbackAsync { get; set; } /// - /// 获得/设置 客户端组件脚本初始化完成后回调此方法 - /// Gets or sets the callback method for when the client component script initialization is complete. + /// 获得/设置 客户端组件脚本初始化完成回调方法 + /// Gets or sets the callback for when client component script initialization is complete /// [Parameter] public Func? OnInitializedCallbackAsync { get; set; } /// - /// 获得/设置 子组件 - /// Gets or sets the child components. + /// 获得/设置 子组件内容 + /// Gets or sets the child content /// [Parameter] public RenderFragment? ChildContent { get; set; } /// - /// 获得/设置 版本设置 默认 null 未设置 用于本地配置 可通过全局统一配置 - /// Gets or sets the version. Default is null. Used for local configuration and can be configured globally. + /// 获得/设置 版本信息,默认为 null,未设置时可通过全局配置提供 + /// Gets or sets the version information. Default is null. When not set, it can be provided by global configuration /// [Parameter] public string? Version { get; set; } /// - /// 获得/设置 是否启用本地存储布局 默认 null 未设置 - /// Gets or sets whether to enable local storage layout. Default is null. Not set. + /// 获得/设置 是否启用本地存储布局,默认为 null + /// Gets or sets whether local storage layout is enabled. Default is null /// [Parameter] public bool? EnableLocalStorage { get; set; } /// - /// 获得/设置 本地存储前缀 默认 bb-dock - /// Gets or sets the local storage prefix. Default is bb-dock. + /// 获得/设置 本地存储前缀,默认为 bb-dock + /// Gets or sets the local storage prefix. Default is bb-dock /// [Parameter] public string? LocalStoragePrefix { get; set; } /// - /// 获得/设置 DockView 组件主题 默认 Light - /// Gets or sets the DockView component theme. Default is Light. + /// 获得/设置 DockView 组件主题,默认为 Light + /// Gets or sets the DockView component theme. Default is Light /// [Parameter] public DockViewTheme Theme { get; set; } = DockViewTheme.Light; @@ -171,7 +170,8 @@ public partial class DockViewV2 : IDisposable private DockViewOptions? _options = null; /// - /// 组件状态集合 + /// 获得/设置 组件状态集合 + /// Gets or sets the component state collection /// internal ConcurrentDictionary ComponentStates { get; set; } = []; @@ -192,7 +192,6 @@ protected override void OnInitialized() /// /// /// - /// protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); @@ -236,9 +235,8 @@ protected override async Task OnAfterRenderAsync(bool firstRender) /// /// 重置为默认布局 - /// Resets to the default layout. + /// Resets to the default layout /// - /// public async Task Reset(string? layoutConfig = null) { var options = GetOptions(); @@ -250,10 +248,9 @@ public async Task Reset(string? layoutConfig = null) } /// - /// 获得当前布局 Json 字符串 - /// Gets the current layout JSON string. + /// 获得 当前布局 JSON 字符串 + /// Gets the current layout JSON string /// - /// public Task SaveLayout() => InvokeAsync("save", Id); private Task OnThemeChangedAsync(string themeName) @@ -263,8 +260,8 @@ private Task OnThemeChangedAsync(string themeName) } /// - /// 标签页关闭回调方法 由 JavaScript 调用 - /// Tab close callback method called by JavaScript + /// 初始化完成回调方法,由 JavaScript 调用 + /// Initialization callback method called by JavaScript /// [JSInvokable] public async Task InitializedCallbackAsync() @@ -276,8 +273,8 @@ public async Task InitializedCallbackAsync() } /// - /// 标签页关闭回调方法 由 JavaScript 调用 - /// Tab close callback method called by JavaScript + /// 标签页可见状态变更回调方法,由 JavaScript 调用 + /// Tab visibility state change callback method called by JavaScript /// [JSInvokable] public async Task PanelVisibleChangedCallbackAsync(string key, bool status) @@ -304,8 +301,8 @@ public async Task PanelVisibleChangedCallbackAsync(string key, bool status) } /// - /// 锁定回调方法 由 JavaScript 调用 - /// Lock callback method called by JavaScript + /// 锁定状态变更回调方法,由 JavaScript 调用 + /// Lock state change callback method called by JavaScript /// [JSInvokable] public async Task LockChangedCallbackAsync(string[] panels, bool state) @@ -337,10 +334,9 @@ public async Task LockChangedCallbackAsync(string[] panels, bool state) private HashSet _loadTabs = new(); /// - /// 加载指定的标签页 由 JavaScript 调用 - /// Loads the specified tabs called by JavaScript + /// 加载指定标签页的方法,由 JavaScript 调用 + /// Method that loads the specified tabs, called by JavaScript /// - /// [JSInvokable] public Task LoadTabs(List tabs) { @@ -367,7 +363,7 @@ public Task LoadTabs(List tabs) } /// - /// 分割器回调方法 由 JavaScript 调用 + /// 分割器回调方法,由 JavaScript 调用 /// Splitter callback method called by JavaScript /// [JSInvokable] diff --git a/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs b/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs index 202b2a31..9c79847d 100644 --- a/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs +++ b/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs @@ -8,7 +8,7 @@ namespace BootstrapBlazor.Components; /// -/// DockViewComponent 转化器 +/// DockViewComponent 转换器 /// DockViewComponent converter /// class DockViewComponentConverter : JsonConverter> @@ -19,7 +19,6 @@ class DockViewComponentConverter : JsonConverter> /// /// /// - /// /// public override List? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs index e855316e..d30a705c 100644 --- a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs +++ b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs @@ -5,27 +5,32 @@ namespace BootstrapBlazor.Components; /// -/// DockView 组件状态持久化类 +/// DockView 组件状态 +/// DockView component state /// class DockViewComponentState { /// - /// 获得/设置 组件唯一标识值 默认 null 未设置 + /// 获得/设置 组件唯一标识,默认为 null + /// Gets or sets the unique component identifier. Default is null /// public string? Key { get; set; } /// - /// 获得/设置 组件是否锁定 默认 false + /// 获得/设置 组件是否锁定,默认为 false + /// Gets or sets whether the component is locked. Default is false /// public bool? IsLock { get; set; } /// - /// 获得/设置 组件是否可见 默认 false + /// 获得/设置 组件是否可见,默认为 false + /// Gets or sets whether the component is visible. Default is false /// public bool Visible { get; set; } /// - /// 获得/设置 组件是否渲染 默认 false + /// 获得/设置 组件是否已渲染,默认为 false + /// Gets or sets whether the component is rendered. Default is false /// public bool Render { get; set; } } From 9c787a6c9683fbd7b8aca0f48f93f010c89717d3 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 10 Apr 2026 17:04:28 +0800 Subject: [PATCH 11/52] =?UTF-8?q?refactor:=20=E7=B2=BE=E7=AE=80=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index b08e9f10..3857f474 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -186,15 +186,11 @@ protected override void OnParametersSet() Render = _rendered }); - if (state.Visible != Visible) - { - state.Visible = Visible; - } - if (state.IsLock != IsLock) - { - state.IsLock = IsLock; - } + // 同步组件状态到容器状态 + state.Visible = Visible; + state.IsLock = IsLock; + // 同步组件渲染状态 _rendered = state.Render; } } @@ -206,13 +202,4 @@ private async Task OnClickBar() await OnClickTitleBarCallback(); } } - - /// - /// 设置组件可见状态 - /// Sets the component visibility - /// - public void SetVisible(bool visible) - { - Visible = visible; - } } From 9e498b37dc97df71767960652c524fc5cda18617 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Mon, 13 Apr 2026 11:40:47 +0800 Subject: [PATCH 12/52] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=8B=96?= =?UTF-8?q?=E5=8A=A8panel=E5=88=B0=E7=BB=84=E6=97=B6=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=A9=BA=E7=99=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/js/dockview-group.js | 4 ++-- .../BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js | 2 +- .../BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js index 21f13c06..dae4de18 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js @@ -26,14 +26,14 @@ const onAddGroup = group => { dockview._inited && observeGroup(group) } -const addGroupWithPanel = (dockview, panel, localPanel, panels, index) => { +const addGroupWithPanel = (dockview, panel, panels, index) => { if (panel.groupId) { addPanelWidthGroupId(dockview, panel, index) } else { addPanelWidthCreatGroup(dockview, panel, panels) } - deletePanel(dockview, localPanel) + deletePanel(dockview, panel) } const addPanelWidthGroupId = (dockview, panel, index) => { diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js index e4b13270..66d8fe6b 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js @@ -26,8 +26,8 @@ const observePanelActiveChange = panel => { panel.api.onDidVisibilityChange(({ isVisible }) => { const dockview = panel.accessor; if (dockview.params.options.renderer === 'onlyWhenVisible' && dockview._inited && isVisible) { - const visiblePanels = dockview.groups.map(g => g.panels.find(p => p.params.isActive) || g.panels.find(p => p.api.isVisible)) setTimeout(function() { + const visiblePanels = dockview.groups.map(g => g.panels.find(p => p.params.isActive) || g.panels.find(p => p.api.isVisible)) dockview._loadTabs?.fire(visiblePanels.filter(p => Boolean(p)).map(p => p.params.key)); }, 0) } diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index 060aa9f9..db343067 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -239,7 +239,7 @@ const toggleComponent = (dockview, options) => { let indexOfOptions = groupPanels.findIndex(p => p.params.key == panel?.params.key) indexOfOptions = indexOfOptions == -1 ? 0 : indexOfOptions const index = panel && panel.params.index - addGroupWithPanel(dockview, p || panel, panel, panels, index ?? indexOfOptions); + addGroupWithPanel(dockview, panel || p, panels, index ?? indexOfOptions); } }) localPanels.forEach(item => { From ff548b4b375bbf84b90acdd1af8b570302f3973c Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Mon, 13 Apr 2026 12:53:18 +0800 Subject: [PATCH 13/52] =?UTF-8?q?refactor:=20=E8=B0=83=E6=95=B4=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewV2.razor.cs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index ceaeeed3..d4101869 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -149,6 +149,9 @@ public partial class DockViewV2 : IDisposable [Parameter] public DockViewTheme Theme { get; set; } = DockViewTheme.Light; + /// + /// 嵌套 DockView 时生效防止生成冗余的 DOM 结构 + /// [CascadingParameter] private DockViewV2? DockView { get; set; } @@ -331,6 +334,19 @@ public async Task LockChangedCallbackAsync(string[] panels, bool state) } } + /// + /// 分割器回调方法,由 JavaScript 调用 + /// Splitter callback method called by JavaScript + /// + [JSInvokable] + public async Task SplitterCallbackAsync() + { + if (OnSplitterCallbackAsync != null) + { + await OnSplitterCallbackAsync(); + } + } + private HashSet _loadTabs = new(); /// @@ -362,19 +378,6 @@ public Task LoadTabs(List tabs) return Task.CompletedTask; } - /// - /// 分割器回调方法,由 JavaScript 调用 - /// Splitter callback method called by JavaScript - /// - [JSInvokable] - public async Task SplitterCallbackAsync() - { - if (OnSplitterCallbackAsync != null) - { - await OnSplitterCallbackAsync(); - } - } - private void Dispose(bool disposing) { if (disposing) From 80f03dcc77abb15d9f15cc50f0089e174098cd05 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Mon, 13 Apr 2026 15:19:08 +0800 Subject: [PATCH 14/52] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=8F=AF?= =?UTF-8?q?=E8=A7=81=E6=80=A7=E7=BC=93=E5=AD=98=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor | 2 +- .../Components/DockViewComponent.razor.cs | 67 +++++++++++-------- .../Components/DockViewComponentBase.cs | 1 + .../Components/DockViewV2.razor.cs | 50 ++++++++------ .../Data/DockViewComponentState.cs | 8 +-- 5 files changed, 75 insertions(+), 53 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor index 3724dec0..573cc056 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor @@ -11,7 +11,7 @@ { } - @if (_rendered) + @if (IsRender()) { @ChildContent } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 3857f474..252a337b 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -61,6 +61,7 @@ public partial class DockViewComponent /// Gets or sets whether the component is visible. Default is true /// [Parameter] + [JsonIgnore] public bool Visible { get; set; } = true; /// @@ -82,6 +83,7 @@ public partial class DockViewComponent /// Gets or sets whether the component is locked. Default is null. When not set, the DockView configuration is used /// [Parameter] + [JsonIgnore] public bool? IsLock { get; set; } /// @@ -151,13 +153,19 @@ public partial class DockViewComponent [Parameter] [JsonIgnore] public Func? OnClickTitleBarCallback { get; set; } + + [JsonInclude] + [JsonPropertyName("visible")] + private bool JsonVisible => DockView.GetComponentState(Key)?.Visible ?? false; + + [JsonInclude] + [JsonPropertyName("isLock")] + private bool JsonIsLock => DockView.GetComponentState(Key)?.IsLock ?? false; + [CascadingParameter] [NotNull] - [JsonIgnore] private DockViewV2? DockView { get; set; } - private bool _rendered = false; - /// /// /// @@ -166,33 +174,14 @@ protected override void OnInitialized() base.OnInitialized(); Type = DockViewContentType.Component; - } - - /// - /// - /// - protected override void OnParametersSet() - { - base.OnParametersSet(); - // 根据容器状态同步组件状态 - if (!string.IsNullOrEmpty(Key)) + // 增加组件状态 + DockView?.AddComponentState(new DockViewComponentState() { - var state = DockView.ComponentStates.GetOrAdd(Key, key => new DockViewComponentState - { - Key = key, - IsLock = IsLock, - Visible = Visible, - Render = _rendered - }); - - // 同步组件状态到容器状态 - state.Visible = Visible; - state.IsLock = IsLock; - - // 同步组件渲染状态 - _rendered = state.Render; - } + Key = Key, + Visible = Visible, + IsLock = IsLock + }); } private async Task OnClickBar() @@ -202,4 +191,26 @@ private async Task OnClickBar() await OnClickTitleBarCallback(); } } + + private bool IsRender() + { + var render = false; + var state = DockView.GetComponentState(Key); + if (state != null) + { + render = state.Render && state.Visible; + } + return render; + } + + /// + /// + /// + /// + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + DockView.RemoveComponentState(Key); + } } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs index b2073a01..c28150be 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs @@ -41,6 +41,7 @@ public abstract class DockViewComponentBase : IdComponentBase, IDisposable [Parameter] [JsonIgnore] public RenderFragment? ChildContent { get; set; } + [CascadingParameter] private List? Parent { get; set; } diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index d4101869..a176b94a 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -171,12 +171,7 @@ public partial class DockViewV2 : IDisposable [NotNull] private DockViewOptions? _options = null; - - /// - /// 获得/设置 组件状态集合 - /// Gets or sets the component state collection - /// - internal ConcurrentDictionary ComponentStates { get; set; } = []; + private ConcurrentDictionary _componentStates = new(); /// /// @@ -283,7 +278,7 @@ public async Task InitializedCallbackAsync() public async Task PanelVisibleChangedCallbackAsync(string key, bool status) { // 同步更新组件可见状态 - ComponentStates.AddOrUpdate(key, key => + _componentStates.AddOrUpdate(key, key => { return new DockViewComponentState() { @@ -313,7 +308,7 @@ public async Task LockChangedCallbackAsync(string[] panels, bool state) // 同步更新组件锁定状态 foreach (var panel in panels) { - ComponentStates.AddOrUpdate(panel, key => + _componentStates.AddOrUpdate(panel, key => { return new DockViewComponentState() { @@ -357,25 +352,40 @@ public async Task SplitterCallbackAsync() public Task LoadTabs(List tabs) { _loadTabs = tabs.ToHashSet(); + foreach (var componnet in _componentStates) + { + // 标记是否渲染 + componnet.Value.Render = tabs.Contains(componnet.Key); + } + StateHasChanged(); - bool rendered = false; - foreach (var key in ComponentStates.Keys) + return Task.CompletedTask; + } + + internal void AddComponentState(DockViewComponentState state) + { + if (!string.IsNullOrEmpty(state.Key)) { - var state = ComponentStates[key]; + _componentStates.TryAdd(state.Key, state); + } + } - var render = _loadTabs.Contains(key); - if (render != state.Render) - { - state.Render = render; - rendered = true; - } + internal void RemoveComponentState(string? key) + { + if (!string.IsNullOrEmpty(key)) + { + _componentStates.TryRemove(key, out _); } + } - if (rendered) + internal DockViewComponentState? GetComponentState(string? key) + { + DockViewComponentState? state = null; + if (!string.IsNullOrEmpty(key) && _componentStates.TryGetValue(key, out var _state)) { - StateHasChanged(); + state = _state; } - return Task.CompletedTask; + return state; } private void Dispose(bool disposing) diff --git a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs index d30a705c..df40578d 100644 --- a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs +++ b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs @@ -23,13 +23,13 @@ class DockViewComponentState public bool? IsLock { get; set; } /// - /// 获得/设置 组件是否可见,默认为 false - /// Gets or sets whether the component is visible. Default is false + /// 获得/设置 组件是否可见,默认为 true + /// Gets or sets whether the component is visible. Default is true /// - public bool Visible { get; set; } + public bool Visible { get; set; } = true; /// - /// 获得/设置 组件是否已渲染,默认为 false + /// 获得/设置 组件内容是否渲染,默认为 false /// Gets or sets whether the component is rendered. Default is false /// public bool Render { get; set; } From 192b4f1e4b1bbb186d26303b23d5b8373a5fce8e Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Mon, 13 Apr 2026 18:31:50 +0800 Subject: [PATCH 15/52] =?UTF-8?q?refactor:=20=E4=BD=BF=E7=94=A8=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E6=96=B9=E6=B3=95=E7=B2=BE=E7=AE=80=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 26 +++------- .../Converters/DockViewComponentConverter.cs | 2 +- .../DockViewComponentStateExtensions.cs | 49 +++++++++++++++++++ 3 files changed, 57 insertions(+), 20 deletions(-) create mode 100644 src/components/BootstrapBlazor.DockView/Extensions/DockViewComponentStateExtensions.cs diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 252a337b..6e327cb9 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -46,7 +46,6 @@ public partial class DockViewComponent /// Gets or sets the title template. Default is null /// [Parameter] - [JsonIgnore] public RenderFragment? TitleTemplate { get; set; } /// @@ -61,7 +60,6 @@ public partial class DockViewComponent /// Gets or sets whether the component is visible. Default is true /// [Parameter] - [JsonIgnore] public bool Visible { get; set; } = true; /// @@ -83,7 +81,6 @@ public partial class DockViewComponent /// Gets or sets whether the component is locked. Default is null. When not set, the DockView configuration is used /// [Parameter] - [JsonIgnore] public bool? IsLock { get; set; } /// @@ -119,7 +116,6 @@ public partial class DockViewComponent /// Gets or sets the component render mode. Default is null. When not set, the DockView configuration is used /// [Parameter] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Renderer { get; set; } /// @@ -151,17 +147,8 @@ public partial class DockViewComponent /// Gets or sets the click callback for the leading title icon. Default is null /// [Parameter] - [JsonIgnore] public Func? OnClickTitleBarCallback { get; set; } - [JsonInclude] - [JsonPropertyName("visible")] - private bool JsonVisible => DockView.GetComponentState(Key)?.Visible ?? false; - - [JsonInclude] - [JsonPropertyName("isLock")] - private bool JsonIsLock => DockView.GetComponentState(Key)?.IsLock ?? false; - [CascadingParameter] [NotNull] private DockViewV2? DockView { get; set; } @@ -194,13 +181,14 @@ private async Task OnClickBar() private bool IsRender() { - var render = false; var state = DockView.GetComponentState(Key); - if (state != null) - { - render = state.Render && state.Visible; - } - return render; + return state.IsRender(); + } + + internal object? GetState() + { + var state = DockView.GetComponentState(Key); + return state.GetComponentState(this); } /// diff --git a/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs b/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs index 9c79847d..2d50fe29 100644 --- a/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs +++ b/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs @@ -42,7 +42,7 @@ public override void Write(Utf8JsonWriter writer, List va } else if (item is DockViewComponent contentItem) { - writer.WriteRawValue(JsonSerializer.Serialize(contentItem, options)); + writer.WriteRawValue(JsonSerializer.Serialize(contentItem.GetState(), options)); } } writer.WriteEndArray(); diff --git a/src/components/BootstrapBlazor.DockView/Extensions/DockViewComponentStateExtensions.cs b/src/components/BootstrapBlazor.DockView/Extensions/DockViewComponentStateExtensions.cs new file mode 100644 index 00000000..0bb1e036 --- /dev/null +++ b/src/components/BootstrapBlazor.DockView/Extensions/DockViewComponentStateExtensions.cs @@ -0,0 +1,49 @@ +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone + +namespace BootstrapBlazor.Components; + +static class DockViewComponentStateExtensions +{ + extension(DockViewComponentState? state) + { + public bool IsRender() + { + var render = false; + if (state != null) + { + render = state.Render && state.Visible; + } + return render; + } + + public object? GetComponentState(DockViewComponent component) + { + if (state == null) + { + return null; + } + + return new + { + component.Class, + component.Height, + component.Id, + component.IsFloating, + IsLock = state.IsLock, + component.Key, + component.ShowClose, + component.ShowFloat, + component.ShowLock, + component.ShowMaximize, + component.Title, + component.TitleClass, + component.TitleWidth, + component.Type, + Visible = state.Visible, + component.Width + }; + } + } +} From 6a05eb882974047cf85436befe3d5c7194cbe024 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Tue, 14 Apr 2026 10:56:41 +0800 Subject: [PATCH 16/52] =?UTF-8?q?fix:=20=E5=88=87=E6=8D=A2=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=97=B6=E4=B8=8D=E9=9C=80=E8=A6=81=E6=9B=B4=E6=96=B0?= =?UTF-8?q?panel=E7=9A=84visible=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wwwroot/js/dockview-extensions.js | 4 ++-- .../BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index 97d7a17a..f0643702 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -72,10 +72,10 @@ DockviewComponent.prototype.removeGroup = function (...args) { const removePanel = DockviewComponent.prototype.removePanel DockviewComponent.prototype.removePanel = function (...args) { - const panel = args[0] + const panel = args[0], noFiring = args[1] if (!panel.group.locked) { removePanel.apply(this, args) - if (!this.isClearing) { + if (!this.isClearing && noFiring!== true) { this._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); } } diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index db343067..eaf80b29 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -250,7 +250,7 @@ const toggleComponent = (dockview, options) => { let pan = findContentFromPanels(panels, item); if (pan === void 0) { item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key) - dockview.removePanel(item) + dockview.removePanel(item, true) } }) } From 462e41aeb7636445c829b5d5b705be7893f7beb9 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 12:12:47 +0800 Subject: [PATCH 17/52] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=AE=9E=E4=BE=8B=E7=94=A8=E4=BA=8E=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=AE=9E=E4=BE=8B=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 26 +++++++------ .../Components/DockViewV2.razor.cs | 38 +++++++------------ .../Data/DockViewComponentState.cs | 8 +++- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 6e327cb9..386f7695 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -163,7 +163,7 @@ protected override void OnInitialized() Type = DockViewContentType.Component; // 增加组件状态 - DockView?.AddComponentState(new DockViewComponentState() + DockView?.AddComponentState(new DockViewComponentState(this) { Key = Key, Visible = Visible, @@ -171,6 +171,14 @@ protected override void OnInitialized() }); } + /// + /// + /// + protected override void OnParametersSet() + { + base.OnParametersSet(); + } + private async Task OnClickBar() { if (OnClickTitleBarCallback != null) @@ -179,17 +187,13 @@ private async Task OnClickBar() } } - private bool IsRender() - { - var state = DockView.GetComponentState(Key); - return state.IsRender(); - } + private bool IsRender() => DockView.GetComponentState(Key).IsRender(); - internal object? GetState() - { - var state = DockView.GetComponentState(Key); - return state.GetComponentState(this); - } + internal object? GetState() => DockView.GetComponentState(Key).GetComponentState(this); + + internal void SetVisible(bool visible) => Visible = visible; + + internal void SetLock(bool isLock) => IsLock = isLock; /// /// diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index a176b94a..7e7cd840 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -278,18 +278,13 @@ public async Task InitializedCallbackAsync() public async Task PanelVisibleChangedCallbackAsync(string key, bool status) { // 同步更新组件可见状态 - _componentStates.AddOrUpdate(key, key => + if (_componentStates.TryGetValue(key, out var state)) { - return new DockViewComponentState() - { - Key = key, - Visible = status - }; - }, (key, v) => - { - v.Visible = status; - return v; - }); + state.Visible = status; + + // 同步可见状态到组件实例 + state.Component.SetVisible(status); + } // 通知订阅者 if (OnVisibleStateChangedAsync != null) @@ -303,29 +298,24 @@ public async Task PanelVisibleChangedCallbackAsync(string key, bool status) /// Lock state change callback method called by JavaScript /// [JSInvokable] - public async Task LockChangedCallbackAsync(string[] panels, bool state) + public async Task LockChangedCallbackAsync(string[] panels, bool locked) { // 同步更新组件锁定状态 foreach (var panel in panels) { - _componentStates.AddOrUpdate(panel, key => - { - return new DockViewComponentState() - { - Key = key, - IsLock = state - }; - }, (key, v) => + if (_componentStates.TryGetValue(panel, out var state)) { - v.IsLock = state; - return v; - }); + state.IsLock = locked; + + // 同步可见状态到组件实例 + state.Component.SetLock(locked); + } } // 通知订阅者 if (OnLockChangedCallbackAsync != null) { - await OnLockChangedCallbackAsync(panels, state); + await OnLockChangedCallbackAsync(panels, locked); } } diff --git a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs index df40578d..b61884a6 100644 --- a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs +++ b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs @@ -8,7 +8,7 @@ namespace BootstrapBlazor.Components; /// DockView 组件状态 /// DockView component state /// -class DockViewComponentState +class DockViewComponentState(DockViewComponent component) { /// /// 获得/设置 组件唯一标识,默认为 null @@ -33,4 +33,10 @@ class DockViewComponentState /// Gets or sets whether the component is rendered. Default is false /// public bool Render { get; set; } + + /// + /// 获得/设置 组件实例,默认为 null + /// Gets or sets the component instance. Default is null + /// + public DockViewComponent? Component => component; } From b7a6e13c49238dd6a79e1a35d619a274a369801c Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 12:59:46 +0800 Subject: [PATCH 18/52] =?UTF-8?q?chore:=20=E8=B0=83=E6=95=B4=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E7=BB=93=E6=9E=84=E6=96=B9=E4=BE=BF=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewV2.razor | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor index ab5a2550..d3c7047f 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor @@ -3,6 +3,12 @@
From 3ebb364d06f12d7f720fcd999e479174f257e51a Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 13:00:03 +0800 Subject: [PATCH 19/52] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=88=87=E6=8D=A2=E5=90=8C=E6=AD=A5=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 386f7695..76605140 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -177,6 +177,13 @@ protected override void OnInitialized() protected override void OnParametersSet() { base.OnParametersSet(); + + var state = DockView.GetComponentState(Key); + if (state != null) + { + state.Visible = Visible; + state.IsLock = IsLock; + } } private async Task OnClickBar() From 342ec928781f28bb317f16b612a4a625827319f9 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 13:00:18 +0800 Subject: [PATCH 20/52] =?UTF-8?q?refactor:=20=E7=B2=BE=E7=AE=80=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 76605140..d380b049 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -162,13 +162,8 @@ protected override void OnInitialized() Type = DockViewContentType.Component; - // 增加组件状态 - DockView?.AddComponentState(new DockViewComponentState(this) - { - Key = Key, - Visible = Visible, - IsLock = IsLock - }); + // 增加组件状态用于序列化 + DockView?.AddComponentState(new DockViewComponentState(this) { Key = Key }); } /// From 00edccacc80ffe70369e3502d75d3850e2420db1 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Tue, 14 Apr 2026 13:02:13 +0800 Subject: [PATCH 21/52] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E6=8C=89=E9=92=AE=E9=85=8D=E7=BD=AE=E4=B8=8D=E7=94=9F?= =?UTF-8?q?=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css index 6b61ed79..6a805d05 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css +++ b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css @@ -127,6 +127,7 @@ } .bb-dockview .dv-tab-on > .dv-default-tab-content + .dv-default-tab-action, + .bb-dockview .dv-tab-on > .bb-dockview-item-title + .dv-default-tab-action, .bb-dockview .dv-tabs-and-actions-container:has(.dv-tab-on) > .dv-right-actions-container > .bb-dockview-control-icon-close, .bb-dockview .dv-right-actions-container:not(.bb-show-pin) .bb-dockview-control-icon-pin, .bb-dockview .dv-right-actions-container:not(.bb-show-pin) .bb-dockview-control-icon-pushpin, From 11a144c162f83f8d5e0da062e1e37bf2c31a1e01 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 13:05:55 +0800 Subject: [PATCH 22/52] =?UTF-8?q?chore:=20=E6=9B=B4=E6=94=B9=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css index 6a805d05..364742c6 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css +++ b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css @@ -1,4 +1,4 @@ -@import './dockview.css'; +@import './dockview.css'; .bb-dockview { --bb-dockview-padding: .25rem; From a590ab22005d4786b6ce1f63c75b73d4a9b07340 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 13:06:26 +0800 Subject: [PATCH 23/52] chore: bump version 10.0.7 --- .../BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj index 6951692f..99648844 100644 --- a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj +++ b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj @@ -1,7 +1,7 @@  - 10.0.6 + 10.0.7 From 66664472f5d3aba6f3b3c3fec77981651d4166a2 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 13:50:21 +0800 Subject: [PATCH 24/52] =?UTF-8?q?refactor:=20=E7=B2=BE=E7=AE=80=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Converters/DockViewComponentConverter.cs | 2 +- .../DockViewComponentStateExtensions.cs | 34 ++++--------------- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs b/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs index 2d50fe29..9c79847d 100644 --- a/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs +++ b/src/components/BootstrapBlazor.DockView/Converters/DockViewComponentConverter.cs @@ -42,7 +42,7 @@ public override void Write(Utf8JsonWriter writer, List va } else if (item is DockViewComponent contentItem) { - writer.WriteRawValue(JsonSerializer.Serialize(contentItem.GetState(), options)); + writer.WriteRawValue(JsonSerializer.Serialize(contentItem, options)); } } writer.WriteEndArray(); diff --git a/src/components/BootstrapBlazor.DockView/Extensions/DockViewComponentStateExtensions.cs b/src/components/BootstrapBlazor.DockView/Extensions/DockViewComponentStateExtensions.cs index 0bb1e036..4d0e6f0e 100644 --- a/src/components/BootstrapBlazor.DockView/Extensions/DockViewComponentStateExtensions.cs +++ b/src/components/BootstrapBlazor.DockView/Extensions/DockViewComponentStateExtensions.cs @@ -8,42 +8,20 @@ static class DockViewComponentStateExtensions { extension(DockViewComponentState? state) { + /// + /// 判断组件是否需要渲染 + /// Determine whether the component needs to be rendered + /// public bool IsRender() { + // 如果组件 Visible false 表示组件不可见,此时 Render 也不需要渲染 var render = false; if (state != null) { + // 组件必须可见并且 Active 时才需要渲染 render = state.Render && state.Visible; } return render; } - - public object? GetComponentState(DockViewComponent component) - { - if (state == null) - { - return null; - } - - return new - { - component.Class, - component.Height, - component.Id, - component.IsFloating, - IsLock = state.IsLock, - component.Key, - component.ShowClose, - component.ShowFloat, - component.ShowLock, - component.ShowMaximize, - component.Title, - component.TitleClass, - component.TitleWidth, - component.Type, - Visible = state.Visible, - component.Width - }; - } } } From 852f9ca4090e86e02700a1d70f0b9efc8ab6ebf9 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 13:50:52 +0800 Subject: [PATCH 25/52] =?UTF-8?q?refactor:=20=E7=BB=84=E4=BB=B6=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=9B=B4=E6=8E=A5=E8=B0=83=E7=94=A8=20DockView=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 5 ++-- .../Components/DockViewV2.razor.cs | 27 ++++++++++++++++--- .../Data/DockViewComponentState.cs | 6 ++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index d380b049..60d0c6f7 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -173,6 +173,7 @@ protected override void OnParametersSet() { base.OnParametersSet(); + // 同步组件状态到缓存 var state = DockView.GetComponentState(Key); if (state != null) { @@ -189,9 +190,7 @@ private async Task OnClickBar() } } - private bool IsRender() => DockView.GetComponentState(Key).IsRender(); - - internal object? GetState() => DockView.GetComponentState(Key).GetComponentState(this); + private bool IsRender() => DockView.IsRender(Key); internal void SetVisible(bool visible) => Visible = visible; diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 7e7cd840..151b776e 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -249,7 +249,7 @@ public async Task Reset(string? layoutConfig = null) /// 获得 当前布局 JSON 字符串 /// Gets the current layout JSON string /// - public Task SaveLayout() => InvokeAsync("save", Id); + public Task SaveLayout() => InvokeAsync("save", Id); private Task OnThemeChangedAsync(string themeName) { @@ -341,6 +341,7 @@ public async Task SplitterCallbackAsync() [JSInvokable] public Task LoadTabs(List tabs) { + // 注意渲染方式 DockViewRenderMode 为 DockViewRenderMode.OnlyWhenVisible 时此逻辑生效 _loadTabs = tabs.ToHashSet(); foreach (var componnet in _componentStates) { @@ -354,6 +355,11 @@ public Task LoadTabs(List tabs) internal void AddComponentState(DockViewComponentState state) { + if (Renderer == DockViewRenderMode.Always) + { + return; + } + if (!string.IsNullOrEmpty(state.Key)) { _componentStates.TryAdd(state.Key, state); @@ -362,6 +368,11 @@ internal void AddComponentState(DockViewComponentState state) internal void RemoveComponentState(string? key) { + if (Renderer == DockViewRenderMode.Always) + { + return; + } + if (!string.IsNullOrEmpty(key)) { _componentStates.TryRemove(key, out _); @@ -371,13 +382,23 @@ internal void RemoveComponentState(string? key) internal DockViewComponentState? GetComponentState(string? key) { DockViewComponentState? state = null; - if (!string.IsNullOrEmpty(key) && _componentStates.TryGetValue(key, out var _state)) + if (Renderer == DockViewRenderMode.OnlyWhenVisible) { - state = _state; + if (!string.IsNullOrEmpty(key) && _componentStates.TryGetValue(key, out var _state)) + { + state = _state; + } } + return state; } + internal bool IsRender(string? key) => Renderer switch + { + DockViewRenderMode.OnlyWhenVisible => GetComponentState(key)?.IsRender() ?? false, + _ => true + }; + private void Dispose(bool disposing) { if (disposing) diff --git a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs index b61884a6..1fbf0120 100644 --- a/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs +++ b/src/components/BootstrapBlazor.DockView/Data/DockViewComponentState.cs @@ -32,11 +32,15 @@ class DockViewComponentState(DockViewComponent component) /// 获得/设置 组件内容是否渲染,默认为 false /// Gets or sets whether the component is rendered. Default is false ///
+ /// + /// 组件内容是否渲染,默认为 false,只有当组件可见时并且当前状态为 Active 时才会渲染组件内容 + /// Whether the component content is rendered. Default is false. The content is only rendered when the component is visible and the current state is Active. + /// public bool Render { get; set; } /// /// 获得/设置 组件实例,默认为 null /// Gets or sets the component instance. Default is null /// - public DockViewComponent? Component => component; + public DockViewComponent Component => component; } From 7ae960439576f72096bd8c86f184e880096d8853 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 13:54:45 +0800 Subject: [PATCH 26/52] =?UTF-8?q?refactor:=20=E4=BB=A3=E7=A0=81=E5=86=85?= =?UTF-8?q?=E8=81=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 7 +---- .../Components/DockViewV2.razor.cs | 28 ++++++++++++++----- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 60d0c6f7..138c4349 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -174,12 +174,7 @@ protected override void OnParametersSet() base.OnParametersSet(); // 同步组件状态到缓存 - var state = DockView.GetComponentState(Key); - if (state != null) - { - state.Visible = Visible; - state.IsLock = IsLock; - } + DockView.UpdateComponentState(Key, Visible, IsLock); } private async Task OnClickBar() diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 151b776e..84a0bcce 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -379,7 +379,27 @@ internal void RemoveComponentState(string? key) } } - internal DockViewComponentState? GetComponentState(string? key) + internal void UpdateComponentState(string? key, bool visible, bool? isLock) + { + if (Renderer == DockViewRenderMode.Always) + { + return; + } + + if (!string.IsNullOrEmpty(key) && _componentStates.TryGetValue(key, out var state)) + { + state.Visible = visible; + state.IsLock = isLock; + } + } + + internal bool IsRender(string? key) => Renderer switch + { + DockViewRenderMode.OnlyWhenVisible => GetComponentState(key)?.IsRender() ?? false, + _ => true + }; + + private DockViewComponentState? GetComponentState(string? key) { DockViewComponentState? state = null; if (Renderer == DockViewRenderMode.OnlyWhenVisible) @@ -393,12 +413,6 @@ internal void RemoveComponentState(string? key) return state; } - internal bool IsRender(string? key) => Renderer switch - { - DockViewRenderMode.OnlyWhenVisible => GetComponentState(key)?.IsRender() ?? false, - _ => true - }; - private void Dispose(bool disposing) { if (disposing) From 20a1c74a436c9bd369e8145c68b5cd8cd1b27a04 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Tue, 14 Apr 2026 16:01:48 +0800 Subject: [PATCH 27/52] =?UTF-8?q?fix=EF=BC=9A=E5=88=A0=E9=99=A4panel?= =?UTF-8?q?=E6=97=B6=E9=9A=90=E8=97=8F=E7=A9=BA=E7=9A=84group=E5=8F=8Aenab?= =?UTF-8?q?leLocalStorage=E4=B8=8D=E8=B5=B7=E4=BD=9C=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index eaf80b29..fbf25cda 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -6,7 +6,6 @@ import { getConfig, reloadFromConfig, loadPanelsFromLocalstorage, saveConfig } f import './dockview-extensions.js' const cerateDockview = (el, options) => { - options.enableLocalStorage = true; const theme = options.theme || "dockview-theme-light"; const template = el.querySelector('template'); options.renderer ??= 'onlyWhenVisible'; // onlyWhenVisible | partial | always @@ -250,7 +249,11 @@ const toggleComponent = (dockview, options) => { let pan = findContentFromPanels(panels, item); if (pan === void 0) { item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key) + const group = item.group dockview.removePanel(item, true) + if (group.panels.length === 0) { + dockview.setVisible(group, false) + } } }) } From 57e12402866b51d1b282a6cd5a5e5db9751bcd65 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 16:28:26 +0800 Subject: [PATCH 28/52] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E6=A0=87=E7=AD=BE=E9=98=B2=E6=AD=A2=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewComponent.razor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs index 138c4349..663459a8 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor.cs @@ -147,6 +147,7 @@ public partial class DockViewComponent /// Gets or sets the click callback for the leading title icon. Default is null ///
[Parameter] + [JsonIgnore] public Func? OnClickTitleBarCallback { get; set; } [CascadingParameter] From d8b1250913c7d9c87a45d16b76519036e24be83c Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 14 Apr 2026 16:32:00 +0800 Subject: [PATCH 29/52] =?UTF-8?q?revert:=20=E6=92=A4=E9=94=80=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewV2.razor | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor index d3c7047f..ab5a2550 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor @@ -3,12 +3,6 @@
From 46482e24bd9ccf16bfe8808faf8b2d0eddaeef12 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Tue, 14 Apr 2026 16:54:08 +0800 Subject: [PATCH 30/52] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=9A=90?= =?UTF-8?q?=E8=97=8F=E7=BB=84=E6=97=B6=E5=87=BA=E7=8E=B0=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84=E7=BA=BF=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css index 364742c6..8bcc16a1 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css +++ b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css @@ -299,3 +299,7 @@ .bb-dockview .dv-render-overlay-float { z-index: -1 !important; } + +.bb-dockview .dv-view-container > .dv-view:first-child:not(.visible) + .dv-view.visible::before { + height: 0; +} \ No newline at end of file From 6c852a3153b09cd18e1d6c45d7e3739ed07a31d0 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Wed, 15 Apr 2026 16:02:24 +0800 Subject: [PATCH 31/52] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E6=95=B0=E6=8D=AEdockview=E6=9B=B4=E6=96=B0=E4=B8=8D?= =?UTF-8?q?=E5=AF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wwwroot/css/dockview-bb.css | 4 +- .../wwwroot/js/dockview-extensions.js | 12 +++++- .../wwwroot/js/dockview-panel.js | 25 +++++------ .../wwwroot/js/dockview-utils.js | 41 ++++++++++++------- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css index 8bcc16a1..60a3a679 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css +++ b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css @@ -300,6 +300,6 @@ z-index: -1 !important; } -.bb-dockview .dv-view-container > .dv-view:first-child:not(.visible) + .dv-view.visible::before { +/* .bb-dockview .dv-view-container > .dv-view:first-child:not(.visible) + .dv-view.visible::before { height: 0; -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index f0643702..fd8d591f 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -75,10 +75,20 @@ DockviewComponent.prototype.removePanel = function (...args) { const panel = args[0], noFiring = args[1] if (!panel.group.locked) { removePanel.apply(this, args) - if (!this.isClearing && noFiring!== true) { + if (!this.isClearing) { this._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); } } + if (noFiring !== true) { + if (panel.view.content.element) { + if (panel.titleMenuEle) { + panel.view.content.element.append(panel.titleMenuEle) + } + if (this.params.template) { + this.params.template.append(panel.view.content.element) + } + } + } } const setVisible = DockviewComponent.prototype.setVisible diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js index 66d8fe6b..59602cb3 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js @@ -11,10 +11,11 @@ const observePanelActiveChange = panel => { panel.api.onDidActiveChange(({ isActive }) => { if (isActive && !panel.group.api.isMaximized()) { saveConfig(panel.accessor) - if (panel.group.panels.length < 2) return - panel.group.panels.filter(p => p != panel.group.activePanel && p.renderer == 'onlyWhenVisible').forEach(p => { - appendTemplatePanelEle(p) - }) + if (panel.group.panels.length >= 2){ + panel.group.panels.filter(p => p != panel.group.activePanel && p.renderer == 'onlyWhenVisible').forEach(p => { + appendTemplatePanelEle(p) + }) + } } if (isActive && panel.group.getParams().floatType == 'drawer') { setDrawerTitle(panel.group) @@ -79,14 +80,14 @@ const onRemovePanel = event => { }) } - if (event.view.content.element) { - if (event.titleMenuEle) { - event.view.content.element.append(event.titleMenuEle) - } - if (dockview.params.template) { - dockview.params.template.append(event.view.content.element) - } - } + // if (event.view.content.element) { + // if (event.titleMenuEle) { + // event.view.content.element.append(event.titleMenuEle) + // } + // if (dockview.params.template) { + // dockview.params.template.append(event.view.content.element) + // } + // } } const appendTemplatePanelEle = (panel) => { diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index fbf25cda..3702fd0b 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -109,6 +109,9 @@ const initDockview = (dockview, options, template) => { const visiblePanels = groups.filter(g => g.isVisible).map(g => g.panels.find(p => p.params.isActive) || g.panels.find(p => p.api.isVisible)) dockview._loadTabs?.fire(visiblePanels.filter(p => Boolean(p)).map(p => p.params.key)); } + if (options.renderer === 'always') { + dockview._loadTabs?.fire(dockview.panels.map(p => p.params.key)); + } const { floatingGroups } = dockview.params dockview.floatingGroups.forEach(fg => { const { top, right, bottom, left } = floatingGroups.find(g => g.data.id == fg.group.id).position @@ -228,29 +231,37 @@ const setWidth = (target, dockview) => { } const toggleComponent = (dockview, options) => { - const panels = getPanelsFromOptions(options).filter(p => p.params.visible) - const localPanels = dockview.panels + const optionsPanels = getPanelsFromOptions(options); + const panels = optionsPanels.filter(p => p.params.visible); + const localPanels = dockview.panels; panels.forEach(p => { const pan = findContentFromPanels(localPanels, p); if (pan === void 0) { - const panel = findContentFromPanels(dockview.params.panels, p); - const groupPanels = panels.filter(p1 => p1.params.parentId == p.params.parentId) - let indexOfOptions = groupPanels.findIndex(p => p.params.key == panel?.params.key) - indexOfOptions = indexOfOptions == -1 ? 0 : indexOfOptions - const index = panel && panel.params.index - addGroupWithPanel(dockview, panel || p, panels, index ?? indexOfOptions); + const panel = findContentFromPanels(dockview.params.panels, p) || p; + panel.params = { ...panel.params, ...p.params }; + const groupPanels = panels.filter(p1 => p1.params.parentId == p.params.parentId); + let indexOfOptions = groupPanels.findIndex(p => p.params.key == panel?.params.key); + indexOfOptions = indexOfOptions == -1 ? 0 : indexOfOptions; + // const index = panel && panel.params.index + addGroupWithPanel(dockview, panel, panels, indexOfOptions); + } + else { + if ( pan.title !== p.title ) { + pan.setTitle(p.title) + } + pan._params = { + ...pan.params, + ...p.params + } } }) localPanels.forEach(item => { - const title = panels.find(p => p.params.key == item.params.key)?.title; - if ( title && item.title !== title ) { - item.setTitle(title) - } let pan = findContentFromPanels(panels, item); if (pan === void 0) { - item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key) - const group = item.group - dockview.removePanel(item, true) + item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key); + const group = item.group; + const noFiring = !optionsPanels.some(p => p.params.key == item.params.key || p.id == item.id || p.title == item.title); + dockview.removePanel(item, noFiring) if (group.panels.length === 0) { dockview.setVisible(group, false) } From 2a1ef0e491733c4e7dde2608c17610446df65d46 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Wed, 15 Apr 2026 17:44:07 +0800 Subject: [PATCH 32/52] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E6=95=B0=E6=8D=AEdockview=E5=87=BA=E7=8E=B0=E7=A9=BA?= =?UTF-8?q?=E7=99=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index 3702fd0b..6563f4d3 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -260,7 +260,8 @@ const toggleComponent = (dockview, options) => { if (pan === void 0) { item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key); const group = item.group; - const noFiring = !optionsPanels.some(p => p.params.key == item.params.key || p.id == item.id || p.title == item.title); + const localKeys = [...localPanels.map(p => p.params.key), ...dockview.params.panels.map(p => p.params.key)] + const noFiring = !(optionsPanels.length === localKeys.length && localKeys.every(key => optionsPanels.some(optionsPanel => optionsPanel.params.key === key) )); dockview.removePanel(item, noFiring) if (group.panels.length === 0) { dockview.setVisible(group, false) From 2e4d3af687ecad930091fba59a6c54e64689d4e3 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 15 Apr 2026 20:42:08 +0800 Subject: [PATCH 33/52] chore: bump version 10.0.8-beta01 --- .../BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj index 99648844..30a9d331 100644 --- a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj +++ b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj @@ -1,7 +1,7 @@  - 10.0.7 + 10.0.8-beta01 From c440af1f970a08042d804141b391c195adcb7f2c Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 16 Apr 2026 10:02:11 +0800 Subject: [PATCH 34/52] chore: bump version 10.0.8-beta02 --- .../BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj index 30a9d331..afd5375d 100644 --- a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj +++ b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj @@ -1,7 +1,7 @@  - 10.0.8-beta01 + 10.0.8-beta02 From c095c997b0cd9f5a08b20ea8424f4e5135a7a26b Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 16 Apr 2026 14:53:46 +0800 Subject: [PATCH 35/52] feat(DockViewConfig): add FirstRender parameter --- .../BootstrapBlazor.DockView/Components/DockViewConfig.cs | 6 ++++++ .../Components/DockViewV2.razor.cs | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs index 4605efd7..78b6b7d6 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs @@ -12,6 +12,12 @@ namespace BootstrapBlazor.Components; /// class DockViewConfig { + /// + /// 获得/设置 是否首次加载,默认为 false + /// Gets or sets whether it is the first render. Default is false + /// + public bool FirstRender { get; set; } + /// /// 获得/设置 是否启用本地布局持久化,默认为 true /// Gets or sets whether local layout persistence is enabled. Default is true diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 84a0bcce..0e3c6194 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -203,9 +203,9 @@ protected override async Task OnAfterRenderAsync(bool firstRender) /// /// /// - protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, GetOptions()); + protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, GetOptions(true)); - private DockViewConfig GetOptions() => new() + private DockViewConfig GetOptions(bool firstRender = false) => new() { EnableLocalStorage = EnableLocalStorage ?? _options.EnableLocalStorage ?? false, LocalStorageKey = $"{GetPrefixKey()}-{Name}-{GetVersion()}", @@ -224,7 +224,8 @@ protected override async Task OnAfterRenderAsync(bool firstRender) LockChangedCallback = nameof(LockChangedCallbackAsync), SplitterCallback = nameof(SplitterCallbackAsync), Contents = _components, - LoadTabs = nameof(LoadTabs) + LoadTabs = nameof(LoadTabs), + FirstRender = firstRender }; private string GetVersion() => Version ?? _options.Version ?? "v1"; From 161471ad30199d28a7c0b1e05216cb02f0efbca6 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 16 Apr 2026 15:11:36 +0800 Subject: [PATCH 36/52] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=94=B9=20FirstRen?= =?UTF-8?q?der=20=E5=8F=82=E6=95=B0=E5=80=BC=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/DockViewV2.razor.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 0e3c6194..0dd5f112 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -172,6 +172,7 @@ public partial class DockViewV2 : IDisposable [NotNull] private DockViewOptions? _options = null; private ConcurrentDictionary _componentStates = new(); + private bool _firstLoad = true; /// /// @@ -203,9 +204,9 @@ protected override async Task OnAfterRenderAsync(bool firstRender) /// /// /// - protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, GetOptions(true)); + protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, GetOptions()); - private DockViewConfig GetOptions(bool firstRender = false) => new() + private DockViewConfig GetOptions() => new() { EnableLocalStorage = EnableLocalStorage ?? _options.EnableLocalStorage ?? false, LocalStorageKey = $"{GetPrefixKey()}-{Name}-{GetVersion()}", @@ -225,7 +226,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) SplitterCallback = nameof(SplitterCallbackAsync), Contents = _components, LoadTabs = nameof(LoadTabs), - FirstRender = firstRender + FirstRender = _firstLoad }; private string GetVersion() => Version ?? _options.Version ?? "v1"; @@ -265,6 +266,7 @@ private Task OnThemeChangedAsync(string themeName) [JSInvokable] public async Task InitializedCallbackAsync() { + _firstLoad = false; if (OnInitializedCallbackAsync != null) { await OnInitializedCallbackAsync(); From 58be1e3f031951603d780f473ac790c059fbcf30 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 16 Apr 2026 15:28:05 +0800 Subject: [PATCH 37/52] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=A6=96?= =?UTF-8?q?=E6=AC=A1=E6=B8=B2=E6=9F=93=E4=B8=8D=E7=A7=BB=E5=8A=A8=20Panel?= =?UTF-8?q?=20=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wwwroot/js/dockview-extensions.js | 6 +++--- .../BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index fd8d591f..4998c2ce 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -1,4 +1,4 @@ -import { DockviewComponent, DockviewGroupPanel, getGridLocation, getRelativeLocation, DockviewEmitter } from "./dockview-core.esm.js" +import { DockviewComponent, DockviewGroupPanel, getGridLocation, getRelativeLocation, DockviewEmitter } from "./dockview-core.esm.js" import { getConfigFromStorage, saveConfig } from "./dockview-config.js" import { disposeGroup, removeDrawerBtn } from "./dockview-group.js" @@ -72,14 +72,14 @@ DockviewComponent.prototype.removeGroup = function (...args) { const removePanel = DockviewComponent.prototype.removePanel DockviewComponent.prototype.removePanel = function (...args) { - const panel = args[0], noFiring = args[1] + const panel = args[0], moveToTemplate = args[1] if (!panel.group.locked) { removePanel.apply(this, args) if (!this.isClearing) { this._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); } } - if (noFiring !== true) { + if (moveToTemplate) { if (panel.view.content.element) { if (panel.titleMenuEle) { panel.view.content.element.append(panel.titleMenuEle) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index 6563f4d3..ef1d7767 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -21,7 +21,7 @@ const cerateDockview = (el, options) => { createComponent: option => new DockviewPanelContent(option) }); initDockview(dockview, options, template); - + dockview.firstLoad = true; dockview.init(); return dockview; } @@ -260,9 +260,8 @@ const toggleComponent = (dockview, options) => { if (pan === void 0) { item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key); const group = item.group; - const localKeys = [...localPanels.map(p => p.params.key), ...dockview.params.panels.map(p => p.params.key)] - const noFiring = !(optionsPanels.length === localKeys.length && localKeys.every(key => optionsPanels.some(optionsPanel => optionsPanel.params.key === key) )); - dockview.removePanel(item, noFiring) + const moveToTemplate = !dockview.firstLoad; + dockview.removePanel(item, moveToTemplate) if (group.panels.length === 0) { dockview.setVisible(group, false) } From 3aabbcaf0f7e17573619064690f856bfd64a5615 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 16 Apr 2026 15:28:19 +0800 Subject: [PATCH 38/52] =?UTF-8?q?Revert=20"refactor:=20=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=20FirstRender=20=E5=8F=82=E6=95=B0=E5=80=BC=E9=80=BB=E8=BE=91"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 161471ad30199d28a7c0b1e05216cb02f0efbca6. --- .../Components/DockViewV2.razor.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 0dd5f112..0e3c6194 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -172,7 +172,6 @@ public partial class DockViewV2 : IDisposable [NotNull] private DockViewOptions? _options = null; private ConcurrentDictionary _componentStates = new(); - private bool _firstLoad = true; /// /// @@ -204,9 +203,9 @@ protected override async Task OnAfterRenderAsync(bool firstRender) /// /// /// - protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, GetOptions()); + protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, GetOptions(true)); - private DockViewConfig GetOptions() => new() + private DockViewConfig GetOptions(bool firstRender = false) => new() { EnableLocalStorage = EnableLocalStorage ?? _options.EnableLocalStorage ?? false, LocalStorageKey = $"{GetPrefixKey()}-{Name}-{GetVersion()}", @@ -226,7 +225,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) SplitterCallback = nameof(SplitterCallbackAsync), Contents = _components, LoadTabs = nameof(LoadTabs), - FirstRender = _firstLoad + FirstRender = firstRender }; private string GetVersion() => Version ?? _options.Version ?? "v1"; @@ -266,7 +265,6 @@ private Task OnThemeChangedAsync(string themeName) [JSInvokable] public async Task InitializedCallbackAsync() { - _firstLoad = false; if (OnInitializedCallbackAsync != null) { await OnInitializedCallbackAsync(); From 5f04f3819bd4b7f6f1cd2089227f69bfd6214012 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 16 Apr 2026 15:28:28 +0800 Subject: [PATCH 39/52] Revert "feat(DockViewConfig): add FirstRender parameter" This reverts commit c095c997b0cd9f5a08b20ea8424f4e5135a7a26b. --- .../BootstrapBlazor.DockView/Components/DockViewConfig.cs | 6 ------ .../Components/DockViewV2.razor.cs | 7 +++---- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs index 78b6b7d6..4605efd7 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs @@ -12,12 +12,6 @@ namespace BootstrapBlazor.Components; /// class DockViewConfig { - /// - /// 获得/设置 是否首次加载,默认为 false - /// Gets or sets whether it is the first render. Default is false - /// - public bool FirstRender { get; set; } - /// /// 获得/设置 是否启用本地布局持久化,默认为 true /// Gets or sets whether local layout persistence is enabled. Default is true diff --git a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs index 0e3c6194..84a0bcce 100644 --- a/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs +++ b/src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs @@ -203,9 +203,9 @@ protected override async Task OnAfterRenderAsync(bool firstRender) /// /// /// - protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, GetOptions(true)); + protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, GetOptions()); - private DockViewConfig GetOptions(bool firstRender = false) => new() + private DockViewConfig GetOptions() => new() { EnableLocalStorage = EnableLocalStorage ?? _options.EnableLocalStorage ?? false, LocalStorageKey = $"{GetPrefixKey()}-{Name}-{GetVersion()}", @@ -224,8 +224,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) LockChangedCallback = nameof(LockChangedCallbackAsync), SplitterCallback = nameof(SplitterCallbackAsync), Contents = _components, - LoadTabs = nameof(LoadTabs), - FirstRender = firstRender + LoadTabs = nameof(LoadTabs) }; private string GetVersion() => Version ?? _options.Version ?? "v1"; From a5fa2989cd379f12e56d8b7a27883ba7efebd153 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 16 Apr 2026 17:11:05 +0800 Subject: [PATCH 40/52] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=20firstLoa?= =?UTF-8?q?d=20=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index ef1d7767..b97cd83e 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -60,6 +60,7 @@ const initDockview = (dockview, options, template) => { else { toggleComponent(dockview, options); } + dockview.firstLoad = false; } dockview.reset = options => { From dbe9e03049f5453e93168ef244427a8c5ed2d902 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 16 Apr 2026 21:11:20 +0800 Subject: [PATCH 41/52] chore: bump version 10.0.8-beta03 --- .../BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj index afd5375d..ff72ad88 100644 --- a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj +++ b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj @@ -1,7 +1,7 @@  - 10.0.8-beta02 + 10.0.8-beta03 From 25a88e53a76584bffb05e9dc1d1e04da9d811c1d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 17 Apr 2026 11:17:00 +0800 Subject: [PATCH 42/52] refactor(DockView): add closePanel rewrite function --- .../wwwroot/js/dockview-extensions.js | 37 ++++++++++--------- .../wwwroot/js/dockview-utils.js | 5 +-- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index 4998c2ce..c654aa03 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -1,14 +1,14 @@ -import { DockviewComponent, DockviewGroupPanel, getGridLocation, getRelativeLocation, DockviewEmitter } from "./dockview-core.esm.js" +import { DockviewComponent, DockviewGroupPanel, DockviewGroupPanelModel, getGridLocation, getRelativeLocation, DockviewEmitter } from "./dockview-core.esm.js" import { getConfigFromStorage, saveConfig } from "./dockview-config.js" import { disposeGroup, removeDrawerBtn } from "./dockview-group.js" -DockviewComponent.prototype.on = function (eventType, callback) { +DockviewComponent.prototype.on = function(eventType, callback) { this['_' + eventType] = new DockviewEmitter(); this['_' + eventType].event(callback) } const dispose = DockviewComponent.prototype.dispose; -DockviewComponent.prototype.dispose = function () { +DockviewComponent.prototype.dispose = function() { this.params.observer?.disconnect(); this.groups.forEach(group => { if (group.mutationObserver) { @@ -20,28 +20,29 @@ DockviewComponent.prototype.dispose = function () { } const groupDispose = DockviewGroupPanel.prototype.dispose -DockviewGroupPanel.prototype.dispose = function () { +DockviewGroupPanel.prototype.dispose = function() { disposeGroup(this) groupDispose.call(this) } -DockviewGroupPanel.prototype.getParams = function () { +DockviewGroupPanel.prototype.getParams = function() { return this.activePanel?.params || {} } -DockviewGroupPanel.prototype.setParams = function (data) { +DockviewGroupPanel.prototype.setParams = function(data) { + console.log('setParameter', data); Object.keys(data).forEach(key => { this.panels.forEach(panel => panel.params[key] = data[key]) }) } -DockviewGroupPanel.prototype.removePropsOfParams = function (keys) { +DockviewGroupPanel.prototype.removePropsOfParams = function(keys) { return (keys instanceof Array) ? keys.map(key => this.panels.forEach(panel => delete panel.params[key])) : typeof keys == 'string' ? this.panels.forEach(panel => delete panel.params[keys]) : false } const removeGroup = DockviewComponent.prototype.removeGroup -DockviewComponent.prototype.removeGroup = function (...args) { +DockviewComponent.prototype.removeGroup = function(...args) { if (this.isClearing) { return removeGroup.apply(this, args) } @@ -70,29 +71,31 @@ DockviewComponent.prototype.removeGroup = function (...args) { } } -const removePanel = DockviewComponent.prototype.removePanel -DockviewComponent.prototype.removePanel = function (...args) { - const panel = args[0], moveToTemplate = args[1] +const closePanel = DockviewGroupPanelModel.prototype.closePanel; +DockviewGroupPanelModel.prototype.closePanel = function(panel) { + console.log(panel); if (!panel.group.locked) { - removePanel.apply(this, args) - if (!this.isClearing) { - this._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); + closePanel.call(this, panel); + if (!this.accessor.isClearing) { + this.accessor._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); } } + + const moveToTemplate = !this.accessor.firstLoad; if (moveToTemplate) { if (panel.view.content.element) { if (panel.titleMenuEle) { panel.view.content.element.append(panel.titleMenuEle) } - if (this.params.template) { - this.params.template.append(panel.view.content.element) + if (this.accessor.params.template) { + this.accessor.params.template.append(panel.view.content.element) } } } } const setVisible = DockviewComponent.prototype.setVisible -DockviewComponent.prototype.setVisible = function (...args) { +DockviewComponent.prototype.setVisible = function(...args) { setVisible.apply(this, args) const branch = getBranchByGroup(args[0]) const { orientation, splitview: { sashes } } = branch diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index b97cd83e..044da6e4 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -97,7 +97,7 @@ const initDockview = (dockview, options, template) => { panels.forEach(panel => { const visible = panel.params.visible if (!visible) { - dockview.removePanel(panel) + panel.group.model.closePanel(panel) } dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: visible }); }) @@ -261,8 +261,7 @@ const toggleComponent = (dockview, options) => { if (pan === void 0) { item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key); const group = item.group; - const moveToTemplate = !dockview.firstLoad; - dockview.removePanel(item, moveToTemplate) + group.model.closePanel(item) if (group.panels.length === 0) { dockview.setVisible(group, false) } From 248b1b4e24a82c2a616da599e491b53a8313541d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 17 Apr 2026 11:17:50 +0800 Subject: [PATCH 43/52] chore: bump version 10.0.8-beta04 --- .../BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj index ff72ad88..ae791725 100644 --- a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj +++ b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj @@ -1,7 +1,7 @@  - 10.0.8-beta03 + 10.0.8-beta04 From 1af78811555d9ddd5ae1e11142672fa50fa4881f Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Fri, 17 Apr 2026 13:20:48 +0800 Subject: [PATCH 44/52] =?UTF-8?q?fix:=20=E9=80=9A=E8=BF=87=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E4=BF=AE=E5=A4=8D=E9=9A=90=E8=97=8Fgroup=E6=97=B6?= =?UTF-8?q?=E5=87=BA=E7=8E=B0=E5=A4=9A=E4=BD=99=E7=9A=84=E7=BA=BF=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css index 60a3a679..b19e8dc2 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css +++ b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css @@ -300,6 +300,6 @@ z-index: -1 !important; } -/* .bb-dockview .dv-view-container > .dv-view:first-child:not(.visible) + .dv-view.visible::before { +.bb-dockview .dv-split-view-container.dv-vertical > .dv-view-container > .dv-view:not(:first-child):not(.visible):before { height: 0; -} */ \ No newline at end of file +} From 0e7c357c31cd79a607ea8ad75474113381c899bd Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Fri, 17 Apr 2026 13:25:21 +0800 Subject: [PATCH 45/52] =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0isUpdate?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=88=A4=E6=96=AD=E7=82=B9=E5=87=BB=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E6=97=B6=E4=B8=8D=E5=8F=91=E9=80=81panel=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wwwroot/js/dockview-extensions.js | 2 +- .../BootstrapBlazor.DockView/wwwroot/js/dockview-group.js | 4 ++-- .../BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index c654aa03..07c7a0d3 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -76,7 +76,7 @@ DockviewGroupPanelModel.prototype.closePanel = function(panel) { console.log(panel); if (!panel.group.locked) { closePanel.call(this, panel); - if (!this.accessor.isClearing) { + if (!this.accessor.isClearing && this.accessor.isUpdating !== true) { this.accessor._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); } } diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js index dae4de18..a94cb678 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js @@ -99,7 +99,7 @@ const addPanelWidthGroupId = (dockview, panel, index) => { position: { referenceGroup: group, index: index || 0 }, params: { ...panel.params, rect, packup, visible: true } }) - dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); + dockview.isUpdating !== true && dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); } const addPanelWidthCreatGroup = (dockview, panel, panels) => { @@ -138,7 +138,7 @@ const addPanelWidthCreatGroup = (dockview, panel, panels) => { } if (direction) option.position.direction = direction dockview.addPanel(option); - dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); + dockview.isUpdating !== true && dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); } const getOrientation = function (child, group) { diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index 044da6e4..6a56bf81 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -46,6 +46,7 @@ const initDockview = (dockview, options, template) => { } dockview.update = options => { + dockview.isUpdating = true; if (dockview.params.options.lock !== options.lock) { dockview.params.options.lock = options.lock; toggleGroupLock(dockview, options); @@ -61,6 +62,7 @@ const initDockview = (dockview, options, template) => { toggleComponent(dockview, options); } dockview.firstLoad = false; + dockview.isUpdating = false; } dockview.reset = options => { From 01c4b9c575533687532fccb6c221119875a6b9c3 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 17 Apr 2026 13:50:24 +0800 Subject: [PATCH 46/52] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E8=A7=A6=E5=8F=91=E9=9D=A2=E6=9D=BF=E5=8F=AF=E8=A7=81?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E4=BA=8B=E4=BB=B6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wwwroot/js/dockview-extensions.js | 15 +---- .../wwwroot/js/dockview-group.js | 58 +------------------ .../wwwroot/js/dockview-utils.js | 12 +--- 3 files changed, 6 insertions(+), 79 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index 07c7a0d3..319d9924 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -54,16 +54,6 @@ DockviewComponent.prototype.removeGroup = function(...args) { panel.api.close() }) this.setVisible(group, false) - - // let delPanelsStr = localStorage.getItem(this.params.options.localStorageKey + '-panels') - // let delPanels = delPanelsStr ? JSON.parse(delPanelsStr) : delPanelsStr - // delPanels = delPanels?.map(panel => { - // if (panel.groupId == group.id) { - // panel.groupInvisible = true - // } - // return panel - // }) - // delPanels && localStorage.setItem(this.params.options.localStorageKey + '-panels', JSON.stringify(delPanels)) } else if (type == 'floating') { removeDrawerBtn(group) @@ -72,11 +62,10 @@ DockviewComponent.prototype.removeGroup = function(...args) { } const closePanel = DockviewGroupPanelModel.prototype.closePanel; -DockviewGroupPanelModel.prototype.closePanel = function(panel) { - console.log(panel); +DockviewGroupPanelModel.prototype.closePanel = function(panel, triggerVisibleChangedCallback = true) { if (!panel.group.locked) { closePanel.call(this, panel); - if (!this.accessor.isClearing && this.accessor.isUpdating !== true) { + if (triggerVisibleChangedCallback) { this.accessor._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); } } diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js index a94cb678..fa968dbe 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js @@ -1,4 +1,4 @@ -import { getIcons, getIcon } from "./dockview-icon.js" +import { getIcons, getIcon } from "./dockview-icon.js" import { deletePanel, findContentFromPanels, moveAlwaysRenderPanel } from "./dockview-panel.js" import { saveConfig } from "./dockview-config.js" import { observeGroup } from "./dockview-utils.js" @@ -41,18 +41,6 @@ const addPanelWidthGroupId = (dockview, panel, index) => { let { rect = {}, packup, floatType, drawer, direction = 'left' } = panel.params || {} if (!group) { group = dockview.createGroup({ id: panel.groupId }) - // const floatingGroupPosition = isMaximized ? { - // x: 0, y: 0, - // width: dockview.width, - // height: dockview.height - // } : { - // x: currentPosition?.left || 0, - // y: currentPosition?.top || 0, - // width: currentPosition?.width, - // height: currentPosition?.height - // } - // dockview.addFloatingGroup(group, floatingGroupPosition, { skipRemoveGroup: true }) - // createGroupActions(group); const width = dockview.width > 500 ? 500 : (dockview.width - 10) const height = dockview.height > 460 ? 460 : (dockview.height - 10) const left = (dockview.width - width) / 2 @@ -74,23 +62,16 @@ const addPanelWidthGroupId = (dockview, panel, index) => { if (floatType == 'drawer') { setTimeout(() => createDrawerHandle(group, direction == 'right'), 0); } - // const floatingGroup = createFloatingGroup(group, floatingGroupRect) - const autoHideBtn = group.header.rightActionsContainer.querySelector('.bb-dockview-control-icon-autohide') - if (autoHideBtn) { - // autoHideBtn.style.display = 'none' - } - - // saveConfig(dockview) } else { if (group.api.location.type === 'grid') { let isVisible = dockview.isVisible(group) if (isVisible === false) { dockview.setVisible(group, true) - // isMaximized && group.api.maximize(); } } } + dockview.addPanel({ id: panel.id, title: panel.title, @@ -99,11 +80,10 @@ const addPanelWidthGroupId = (dockview, panel, index) => { position: { referenceGroup: group, index: index || 0 }, params: { ...panel.params, rect, packup, visible: true } }) - dockview.isUpdating !== true && dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); } const addPanelWidthCreatGroup = (dockview, panel, panels) => { - let { position = {}, currentPosition, packupHeight, isPackup, isMaximized } = panel.params || {} + let { position = {}, packupHeight, isPackup, isMaximized } = panel.params || {} let brothers = panels.filter(p => p.params.parentId == panel.params.parentId && p.id != panel.id) let group, direction if (brothers.length > 0 && brothers[0].params.parentType == 'group') { @@ -138,7 +118,6 @@ const addPanelWidthCreatGroup = (dockview, panel, panels) => { } if (direction) option.position.direction = direction dockview.addPanel(option); - dockview.isUpdating !== true && dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); } const getOrientation = function (child, group) { @@ -178,37 +157,6 @@ const createGroupActions = (group, groupType) => { }, 0) addActionEvent(group, actionContainer); } -const observeDisplayChange = (icon, group) => { - const dockview = group.api.accessor - const element = icon.querySelector('.dropdown-menu') - const mutationObserver = new MutationObserver((mutations) => { - mutations.forEach(mutation => { - if (mutation.attributeName == 'class') { - if(mutation.target.classList.contains('show')) { - const currentPanelEle = group.activePanel.view.content.element.parentElement - const childEle = currentPanelEle.children[0] - group.element.querySelector('&>.dv-content-container').append(childEle) - currentPanelEle.style.zIndex = -1 - childEle.wrapperEle = currentPanelEle - } - else { - const panelEleList = [...group.element.querySelector('&>.dv-content-container').children].map(item => { - const wrapperEle = item.wrapperEle - delete item.wrapperEle - wrapperEle.append(item) - return wrapperEle - }) - group.element.parentElement.parentElement.append(...panelEleList) - } - } - }) - }); - group.mutationObserver = mutationObserver - mutationObserver.observe(element, { - attributes: true, - attributeFilter: ["class"], - }); -} const disposeGroup = group => { const { observer } = group.api.accessor.params; diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index 6a56bf81..8411e26f 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -122,20 +122,11 @@ const initDockview = (dockview, options, template) => { fg.group.element.parentElement.style.inset = [top, right, bottom, left] .map(item => typeof item == 'number' ? (item + 'px') : 'auto').join(' ') - // fg.overlay.onDidChangeEnd(e => { - // saveConfig(dockview); - // }) observeOverlayChange(fg.overlay, fg.group) const { floatType, direction } = fg.group.getParams(); if (floatType == 'drawer') { createDrawerHandle(fg.group, direction == 'right') } - else { - const autoHideBtn = fg.group.header.rightActionsContainer.querySelector('.bb-dockview-control-icon-autohide') - if (autoHideBtn) { - // autoHideBtn.style.display = 'none' - } - } observeFloatingGroupLocationChange(fg.group) }) @@ -245,7 +236,6 @@ const toggleComponent = (dockview, options) => { const groupPanels = panels.filter(p1 => p1.params.parentId == p.params.parentId); let indexOfOptions = groupPanels.findIndex(p => p.params.key == panel?.params.key); indexOfOptions = indexOfOptions == -1 ? 0 : indexOfOptions; - // const index = panel && panel.params.index addGroupWithPanel(dockview, panel, panels, indexOfOptions); } else { @@ -263,7 +253,7 @@ const toggleComponent = (dockview, options) => { if (pan === void 0) { item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key); const group = item.group; - group.model.closePanel(item) + group.model.closePanel(item, false) if (group.panels.length === 0) { dockview.setVisible(group, false) } From d0e0b0298ccb543380871c713104727a47304a0c Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 17 Apr 2026 14:10:05 +0800 Subject: [PATCH 47/52] =?UTF-8?q?style:=20=E6=9B=B4=E6=96=B0=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css index b19e8dc2..22fbb120 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css +++ b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css @@ -300,6 +300,6 @@ z-index: -1 !important; } -.bb-dockview .dv-split-view-container.dv-vertical > .dv-view-container > .dv-view:not(:first-child):not(.visible):before { +.dv-split-view-container.dv-vertical .dv-view:not(.visible) + .dv-view:before { height: 0; } From fdbe66f64da841687b3ff39c072a19b73bac7dfc Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 17 Apr 2026 18:33:52 +0800 Subject: [PATCH 48/52] =?UTF-8?q?refactor:=20=E6=94=AF=E6=8C=81=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E7=AB=AF=E6=97=A0=20Key=20=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wwwroot/js/dockview-extensions.js | 3 +-- .../wwwroot/js/dockview-utils.js | 22 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index 319d9924..2fbe90b7 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -62,7 +62,7 @@ DockviewComponent.prototype.removeGroup = function(...args) { } const closePanel = DockviewGroupPanelModel.prototype.closePanel; -DockviewGroupPanelModel.prototype.closePanel = function(panel, triggerVisibleChangedCallback = true) { +DockviewGroupPanelModel.prototype.closePanel = function(panel, triggerVisibleChangedCallback = true, moveToTemplate = true) { if (!panel.group.locked) { closePanel.call(this, panel); if (triggerVisibleChangedCallback) { @@ -70,7 +70,6 @@ DockviewGroupPanelModel.prototype.closePanel = function(panel, triggerVisibleCha } } - const moveToTemplate = !this.accessor.firstLoad; if (moveToTemplate) { if (panel.view.content.element) { if (panel.titleMenuEle) { diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index 8411e26f..b92c0ffe 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -21,7 +21,6 @@ const cerateDockview = (el, options) => { createComponent: option => new DockviewPanelContent(option) }); initDockview(dockview, options, template); - dockview.firstLoad = true; dockview.init(); return dockview; } @@ -34,7 +33,6 @@ const initDockview = (dockview, options, template) => { const config = getConfig(options); dockview.params.floatingGroups = config.floatingGroups || [] dockview.fromJSON(config); - // window.dockview = dockview; } dockview.switchTheme = theme => { @@ -46,7 +44,6 @@ const initDockview = (dockview, options, template) => { } dockview.update = options => { - dockview.isUpdating = true; if (dockview.params.options.lock !== options.lock) { dockview.params.options.lock = options.lock; toggleGroupLock(dockview, options); @@ -61,8 +58,6 @@ const initDockview = (dockview, options, template) => { else { toggleComponent(dockview, options); } - dockview.firstLoad = false; - dockview.isUpdating = false; } dockview.reset = options => { @@ -98,10 +93,12 @@ const initDockview = (dockview, options, template) => { if (options.enableLocalStorage) { panels.forEach(panel => { const visible = panel.params.visible - if (!visible) { + if (visible) { + dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: true }); + } + else { panel.group.model.closePanel(panel) } - dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: visible }); }) delPanels.forEach(panel => { dockview._panelVisibleChanged?.fire({ key: panel.params.key, status: false }); @@ -133,7 +130,7 @@ const initDockview = (dockview, options, template) => { dockview.groups.forEach(group => { observeGroup(group) }) - dockview.element.querySelector('&>.dv-dockview>.dv-branch-node').addEventListener('click', function (e) { + dockview.element.querySelector('&>.dv-dockview>.dv-branch-node').addEventListener('click', function(e) { this.parentElement.querySelectorAll('&>.dv-resize-container-drawer, &>.dv-render-overlay-float-drawer').forEach(item => { item.classList.remove('active') }) @@ -239,7 +236,7 @@ const toggleComponent = (dockview, options) => { addGroupWithPanel(dockview, panel, panels, indexOfOptions); } else { - if ( pan.title !== p.title ) { + if (pan.title !== p.title) { pan.setTitle(p.title) } pan._params = { @@ -248,12 +245,17 @@ const toggleComponent = (dockview, options) => { } } }) + localPanels.forEach(item => { let pan = findContentFromPanels(panels, item); if (pan === void 0) { item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key); const group = item.group; - group.model.closePanel(item, false) + + const moveToTemplate = dockview.firstLoad ?? false; + group.model.closePanel(item, false, moveToTemplate); + dockview.firstLoad = true; + if (group.panels.length === 0) { dockview.setVisible(group, false) } From 475725cf38cf301330d80def298d81958c5bfb63 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Fri, 17 Apr 2026 18:54:08 +0800 Subject: [PATCH 49/52] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0js=E6=B6=88?= =?UTF-8?q?=E9=99=A4=E5=A4=9A=E4=BD=99=E7=9A=84=E7=BA=BF=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wwwroot/css/dockview-bb.css | 10 ++++++++-- .../wwwroot/js/dockview-extensions.js | 4 +++- .../wwwroot/js/dockview-group.js | 7 ++++--- .../wwwroot/js/dockview-utils.js | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css index 22fbb120..b5383eb4 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css +++ b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css @@ -300,6 +300,12 @@ z-index: -1 !important; } -.dv-split-view-container.dv-vertical .dv-view:not(.visible) + .dv-view:before { +/* .dv-split-view-container.dv-vertical .dv-view:not(.visible) + .dv-view:before { height: 0; -} +} */ + +.bb-dockview .dv-split-view-container.dv-vertical > .dv-view-container > .dv-view:not(:first-child):not(.visible):before, +.bb-dockview .dv-split-view-container.dv-vertical > .dv-view-container > .dv-view:first-child:not(.visible) + .dv-view.visible:before, +.bb-dockview .dv-split-view-container.dv-vertical > .dv-view-container > .dv-view.first-visible::before { + height: 0; +} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js index 2fbe90b7..411141b0 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js @@ -1,6 +1,7 @@ import { DockviewComponent, DockviewGroupPanel, DockviewGroupPanelModel, getGridLocation, getRelativeLocation, DockviewEmitter } from "./dockview-core.esm.js" import { getConfigFromStorage, saveConfig } from "./dockview-config.js" import { disposeGroup, removeDrawerBtn } from "./dockview-group.js" +import { markFirstVisibleElement } from "./dockview-utils.js" DockviewComponent.prototype.on = function(eventType, callback) { this['_' + eventType] = new DockviewEmitter(); @@ -84,7 +85,7 @@ DockviewGroupPanelModel.prototype.closePanel = function(panel, triggerVisibleCha const setVisible = DockviewComponent.prototype.setVisible DockviewComponent.prototype.setVisible = function(...args) { - setVisible.apply(this, args) + setVisible.apply(this, args); const branch = getBranchByGroup(args[0]) const { orientation, splitview: { sashes } } = branch @@ -110,6 +111,7 @@ DockviewComponent.prototype.setVisible = function(...args) { } }); } + markFirstVisibleElement(args[0]) } function getBranchByGroup(group) { const groupEle = group.element diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js index fa968dbe..2f9340e4 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js @@ -1,7 +1,7 @@ -import { getIcons, getIcon } from "./dockview-icon.js" +import { getIcons, getIcon } from "./dockview-icon.js" import { deletePanel, findContentFromPanels, moveAlwaysRenderPanel } from "./dockview-panel.js" import { saveConfig } from "./dockview-config.js" -import { observeGroup } from "./dockview-utils.js" +import { observeGroup, markFirstVisibleElement } from "./dockview-utils.js" import EventHandler from '../../BootstrapBlazor/modules/event-handler.js' const onAddGroup = group => { @@ -20,7 +20,8 @@ const onAddGroup = group => { saveConfig(dockview) }) group.model.contentContainer.dropTarget.onDrop(() => { - saveConfig(dockview) + saveConfig(dockview); + markFirstVisibleElement(group) }) createGroupActions(group); dockview._inited && observeGroup(group) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index b92c0ffe..5730eabd 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -83,6 +83,9 @@ const initDockview = (dockview, options, template) => { }) dockview.onDidLayoutFromJSON(() => { + dockview.groups.forEach(group => { + markFirstVisibleElement(group); + }) const handler = setTimeout(() => { clearTimeout(handler); const panels = dockview.panels; @@ -267,5 +270,16 @@ const toggleGroupLock = (dockview, options) => { toggleLock(group, group.header.rightActionsContainer, options.lock) }) } +export const markFirstVisibleElement = group => { + if (!group) return + const viewContainerEle = group.element.parentElement.parentElement; + const className = 'first-visible'; + [...viewContainerEle.children].forEach(ele => { + if (ele.classList.contains(className)) { + ele.classList.remove(className) + } + }) + viewContainerEle.querySelector('.visible')?.classList.add(className); +} export { cerateDockview }; From e7434aba2912a660391c98bb937151b165a33921 Mon Sep 17 00:00:00 2001 From: zhaijunlei <276318515@qq.com> Date: Fri, 17 Apr 2026 18:56:38 +0800 Subject: [PATCH 50/52] =?UTF-8?q?refactor=EF=BC=9A=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=98=AF=E8=A6=81=E5=90=A6=E4=BF=9D=E7=95=99panel=E7=9A=84DOM?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E7=9A=84=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js index 5730eabd..e3fa4216 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js +++ b/src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js @@ -255,9 +255,8 @@ const toggleComponent = (dockview, options) => { item.group.delPanelIndex = item.group.panels.findIndex(p => p.params.key == item.params.key); const group = item.group; - const moveToTemplate = dockview.firstLoad ?? false; + const moveToTemplate = optionsPanels.some(p => p.params.key == item.params.key); group.model.closePanel(item, false, moveToTemplate); - dockview.firstLoad = true; if (group.panels.length === 0) { dockview.setVisible(group, false) From cef1c769a806eec1289162d4b2dd01d70c289855 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 17 Apr 2026 19:09:23 +0800 Subject: [PATCH 51/52] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css index b5383eb4..1b2dcc51 100644 --- a/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css +++ b/src/components/BootstrapBlazor.DockView/wwwroot/css/dockview-bb.css @@ -300,12 +300,8 @@ z-index: -1 !important; } -/* .dv-split-view-container.dv-vertical .dv-view:not(.visible) + .dv-view:before { - height: 0; -} */ - .bb-dockview .dv-split-view-container.dv-vertical > .dv-view-container > .dv-view:not(:first-child):not(.visible):before, .bb-dockview .dv-split-view-container.dv-vertical > .dv-view-container > .dv-view:first-child:not(.visible) + .dv-view.visible:before, .bb-dockview .dv-split-view-container.dv-vertical > .dv-view-container > .dv-view.first-visible::before { height: 0; -} \ No newline at end of file +} From 40f769cd5bbdea773db87bab6d50179d1e021753 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 17 Apr 2026 19:38:56 +0800 Subject: [PATCH 52/52] chore: bump version 10.0.8-beta05 --- .../BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj index ae791725..b3fe2dd0 100644 --- a/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj +++ b/src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj @@ -1,7 +1,7 @@  - 10.0.8-beta04 + 10.0.8-beta05