Avalonia 停靠与原生停靠管理器
TsgcAvaloniaDockManager 将 Avalonia 12 窗口变成 IDE 风格的工作区。工具面板停靠在四条边上,中间是选项卡文档区,用户可以将标题和选项卡拖到放置引导上,将面板自动隐藏到边缘,或让它们浮动在各自的窗口中。每个面板承载您自己的一个 Avalonia 控件,整个布局保存为 JSON。停靠管理器是 sgcNavigation 的一部分,随 sgcUI 2026.11 新推出。
TsgcAvaloniaDockManager 将 Avalonia 12 窗口变成 IDE 风格的工作区。工具面板停靠在四条边上,中间是选项卡文档区,用户可以将标题和选项卡拖到放置引导上,将面板自动隐藏到边缘,或让它们浮动在各自的窗口中。每个面板承载您自己的一个 Avalonia 控件,整个布局保存为 JSON。停靠管理器是 sgcNavigation 的一部分,随 sgcUI 2026.11 新推出。
只需在窗口中放置一个控件。您用代码添加面板,为每个面板指定自己的控件,由用户来安排它们。
每个 TsgcDockPanel 都有 Name、Caption、图标、Kind (dpkTool 或 dpkDocument) 以及它所显示的 Control。工具面板从其 Placement 所在的一侧开始,宽度为 DockSize,具有相同 GroupName 的面板会合并为选项卡。
面板的内容是普通的 Avalonia Control。它成为停靠站点的逻辑子元素和可视子元素,因此 DataContext 从您的窗口向下传递,并且在其面板处于活动状态时进行排列和显示。隐藏的面板会将其控件作为隐藏的子元素保留。
拖动标题或选项卡时,指针下方的分组上会出现指南针,可将该分组沿某一侧拆分,或将面板并入其选项卡;边缘引导将面板停靠到整个站点的某条边上;强调色的预览矩形显示它将占用的空间。按 Esc 可取消拖动。
分组位于嵌套的拆分中,并排或上下堆叠,之间有拆分条。拖动时相邻分组实时调整大小,每个分组至少保持 MinPanelSize。SplitterSize 设置拆分条的宽度。
图钉按钮会将工具面板送到其所在一侧的条上。将鼠标悬停在其选项卡上 AutoHideDelay 毫秒,或单击它,面板就会作为浮出面板滑出到内容上方,用户在别处操作时它会滑回。在代码中,Model.SetAutoHide 可完成相同的操作。
将面板放到引导以外的位置,双击其标题,或在其菜单中选择 Float,它就会移到归您的窗口所有的无边框 Avalonia 窗口中,不出现在任务栏上。浮动窗口拥有自己的树,因此可以将更多面板停靠到其中。每个浮动窗口使用其所在显示器的缩放比例。
文档区有选项卡条,支持固定和已修改的选项卡、关闭按钮、新建选项卡按钮 (DocumentShowNewButton、OnNewDocument) 以及选项卡列表按钮。将文档选项卡拖到某一侧的区域会将其拆分为新的文档分组,双击选项卡则最大化其分组。
Ctrl+F6 在文档间循环,Alt+F7 在工具面板间循环,Shift+Esc 隐藏活动的工具面板,Alt+Minus 打开包含 Float、Dock、Auto Hide、Hide 和 Close 的面板菜单。Ctrl+Tab、Ctrl+W 和 Ctrl+F4 也作为停靠快捷键处理。使用 TsgcAvaloniaCommandPalette 时,停靠管理器还会为每个面板列出一个 Window 命令。
屏幕阅读器通过 UI Automation 将站点识别为名为“Dock site”的窗格,分组对应窗格,条对应选项卡项,拆分条对应带范围值的分隔符。当 FlowDirection 为从右到左时,整个站点会镜像。界面外观按窗口的渲染缩放比例绘制。
SaveLayout、SaveLayoutToFile 和 SaveLayoutToStream 写出布局,LoadLayout 方法将其读回,并把浮动窗口限制在屏幕的工作区内。JSON 文本与 Delphi 模型的相同。OnRestorePanel 会为已保存布局中提到、而当前会话尚未打开的面板创建控件。
Theme 在浅色、深色、高对比度和自定义主题之间切换停靠管理器,AccentColor 设置活动标题的强调色。将 sgcUIApplication.ThemePreset 设为 Fluent 预设后,停靠管理器与其他所有 sgcUI 控件一样使用 WinUI 3 的颜色绘制。
停靠界面的标题 (Close、Auto Hide、Maximize、Float、Dock、Hide、“No open documents”以及屏幕阅读器读出的名称) 都经过 sgcUILang,sgcUI 翻译包涵盖西班牙语、德语、法语、意大利语、荷兰语、波兰语、葡萄牙语、土耳其语、日语、韩语和中文。
这是一个使用 FluentTheme、基于 net8.0 的小型 Avalonia 12 应用的完整窗口。它已针对当前的 sgcNavigation 源代码 (即 sgcUI 2026.11 的代码) 编译,结果为 0 个错误和 0 个警告。
sgcUI 的 Avalonia 程序集将其控件映射到同一个命名空间 URI,因此 sgc 前缀可以找到 TsgcAvaloniaDockManager。停靠管理器填满整个窗口:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sgc="https://www.esegece.com/sgcui"
x:Class="DockSample.MainWindow"
Title="Avalonia docking" Width="1100" Height="720">
<sgc:TsgcAvaloniaDockManager x:Name="dockManager"
DocumentShowNewButton="True"
SplitterSize="5"
AutoHideDelay="400"/>
</Window>三个工具面板和两个文档在 BeginUpdate 和 EndUpdate 之间添加,因此只会排布一次。Output 面板以自动隐藏状态开始,+ 按钮打开新文档,布局在窗口关闭时保存,在窗口再次打开时加载:
using System;
using System.IO;
using Avalonia.Controls;
using esegece.sgcNavigation;
namespace DockSample
{
public partial class MainWindow : Window
{
private readonly string FLayoutFile = Path.Combine(AppContext.BaseDirectory, "layout.json");
private int FUntitled;
public MainWindow()
{
InitializeComponent();
// three tool panels and two documents, placed once at EndUpdate
dockManager.Panels.BeginUpdate();
try
{
AddTool("Explorer", new TreeView(), TsgcDockPlacement.dplLeft, 240);
AddTool("Properties", new StackPanel(), TsgcDockPlacement.dplRight, 260);
AddTool("Output", new TextBox { IsReadOnly = true }, TsgcDockPlacement.dplBottom, 180);
AddDocument("main.cs").Pinned = true;
AddDocument("readme.md");
}
finally
{
dockManager.Panels.EndUpdate();
}
// the Output panel starts auto hidden at the bottom edge
dockManager.Model.SetAutoHide(dockManager.Model.FindPanel("Output"), true);
// the + button of the document area
dockManager.OnNewDocument = (s, aPanel) => AddDocument("Untitled " + (++FUntitled));
// a saved layout names a document this session has not opened yet
dockManager.OnRestorePanel = DockRestorePanel;
// floats show with the window, so load the layout once it is open
Opened += (s, e) =>
{
if (File.Exists(FLayoutFile))
dockManager.LoadLayoutFromFile(FLayoutFile);
};
Closing += (s, e) => dockManager.SaveLayoutToFile(FLayoutFile);
}
private TsgcDockPanel AddTool(string aName, Control aControl, TsgcDockPlacement aPlacement, int aSize)
{
TsgcDockPanel oPanel = dockManager.Panels.Add();
oPanel.Name = aName;
oPanel.Caption = aName;
oPanel.Control = aControl;
oPanel.Placement = aPlacement;
oPanel.DockSize = aSize;
return oPanel;
}
private TsgcDockPanel AddDocument(string aName)
{
TsgcDockPanel oPanel = dockManager.Panels.Add();
oPanel.Name = aName;
oPanel.Caption = aName;
oPanel.Kind = TsgcDockPanelKind.dpkDocument;
oPanel.Control = new TextBox { AcceptsReturn = true };
return oPanel;
}
private void DockRestorePanel(object Sender, TsgcDockPanel aPanel, ref bool aAccept)
{
aAccept = aPanel.Kind == TsgcDockPanelKind.dpkDocument;
if (aAccept)
aPanel.Control = new TextBox { AcceptsReturn = true };
}
}
}App.Initialize 中的一行代码即可将应用中的所有 sgcUI 控件 (包括停靠管理器) 切换为 Fluent 预设:
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
// every sgcUI control, the dock manager included, paints with the Fluent preset
sgcUIApplication.ThemePreset = sgcUICore_Theme.CS_UI_THEME_FLUENT;
}在代码中,DockPanel、FloatPanel、ClosePanel、ShowPanel 和 ActivatePanel 完成用户用鼠标执行的操作。OnPanelDock 最先触发,可以拒绝停靠、浮动或自动隐藏的更改,OnPanelClose 可以让面板保持打开。与其他 sgcNavigation 事件一样,它们是在代码中赋值的委托属性。
Avalonia 停靠管理器是同一个模型的一种视图,sgcNavigation 在 WinForms、WPF 和 Delphi 上也使用该模型。
| 框架 | 控件 | 说明 |
|---|---|---|
| Avalonia 12 | TsgcAvaloniaDockManager | NuGet 包 esegece.sgcNavigation.Avalonia,适用于 net8.0、net9.0 和 net10.0,支持 Windows、Linux 和 macOS。浮动窗口需要经典桌面生命周期。 |
| WPF | TsgcWpfDockManager | 相同的模型,相同的面板,相同的事件。 |
| WinForms | TsgcWinFormsDockManager | 相同的模型,相同的面板,相同的事件。 |
| Delphi VCL | TsgcVCLDockManager | Delphi 模型写出相同的 JSON 布局文本。 |
| Delphi FireMonkey | TsgcFMXDockManager | Delphi 模型写出相同的 JSON 布局文本。 |
这五种都基于 TsgcDockManagerModel 运行,因此同时交付 Delphi 桌面应用和 Avalonia 应用的团队可以保持一套停靠设计和一种布局格式。WinForms、WPF 和 Avalonia 包含在每个 sgcUI .NET 版本中。
停靠管理器及其浮动窗口、文档区和布局持久化是 .NET 版 sgcNavigation 的 Registered 版本的一部分。您可以将 sgcNavigation .NET 作为单个软件包购买,也可以通过 sgcUI .NET 的 Standard、Professional 和 Enterprise 版本获得,均按开发者授权。
sgcNavigation 的免费 Community 软件包包含 sgcNavigation 的其余部分,例如导航栏及其带搜索的树,但不包含停靠管理器和命令面板。要使用停靠,请使用 Registered 软件包。
如果您搜索 Avalonia 停靠,也会找到 Dock,这是一个面向 Avalonia 的开源停靠项目。本页不与其比较功能,请根据您自己的需求对两者进行评估。
Control,停靠管理器绝不会释放它。TsgcAvaloniaDockManager 的浮动窗口是桌面窗口。在浏览器和移动生命周期下,AllowFloating 保持为 False,面板保持停靠状态。适用于 Windows、Linux 和 macOS 上 Avalonia 的停靠外壳:左侧是 Explorer 树,右侧是 Properties,底部是自动隐藏的 Output,以及带有固定和已修改选项卡的文本文档。
将标题或选项卡拖到引导上,放到引导以外的位置使其浮动,或固定工具面板使其自动隐藏。命令面板 (Ctrl+Shift+P) 为每个面板列出一个 Window 命令,复选框用于切换深色主题。
布局在窗口关闭时保存到 DockingShell.layout.json,下次启动时加载,Reset layout 则回到初始布局。已保存的文档通过 OnRestorePanel 获得新的文本框。
位于 sgcUI .NET 演示的 Navigation\DockingShellAvalonia 文件夹中,紧邻 WinForms 的 DockingShell 和 DockingShellWpf。dotnet run -- --test result.txt 会运行其自检。
可以。每个 TsgcDockPanel 的 Control 都是普通的 Avalonia Control,可以是 TreeView、TextBox、UserControl 或您自己的任何视图。它成为停靠站点的子元素,因此 DataContext 从窗口向下传递,停靠管理器在其面板处于活动状态时排列并显示它。停靠管理器绝不会释放它。
浮动窗口是 Avalonia 窗口,因此需要经典桌面生命周期 (IClassicDesktopStyleApplicationLifetime),这正是 Windows、Linux 和 macOS 上 Avalonia 桌面应用所使用的。在浏览器和移动生命周期下,AllowFloating 保持为 False,面板保持停靠状态。
SaveLayout 以 JSON 文本形式返回布局,SaveLayoutToFile 和 SaveLayoutToStream 负责写出。LoadLayout、LoadLayoutFromFile 和 LoadLayoutFromStream 将其读回。请在窗口打开之后再调用 LoadLayout,因为浮动窗口随窗口一起显示。当保存的布局提到尚不存在的面板时,OnRestorePanel 允许您为其创建控件或拒绝它。
停靠管理器是 .NET 版 sgcNavigation 的 Registered 版本的一部分,作为单个软件包销售,并包含在 sgcUI .NET 的 Standard、Professional 和 Enterprise 版本中。sgcNavigation 的免费 Community 软件包不包含它。
TsgcAvaloniaDockManager、TsgcWinFormsDockManager、TsgcWpfDockManager、TsgcVCLDockManager 和 TsgcFMXDockManager 都基于同一个 TsgcDockManagerModel 运行,.NET 模型写出的 JSON 文本与 Delphi 模型完全相同。