承接上篇靜態佈局,本文實現 動態文檔管理:運行期根據使用者操作 (Ribbon 按鈕、選單) 動態建立、關閉、切換 LayoutDocument,並整合主題動態切換、文檔內容載入、狀態持久化。
DockingManager:核心容器,管理 LayoutRoot → LayoutPanel → LayoutDocumentPane → LayoutDocument 階層。LayoutDocument:單一文檔標籤,支援 Title、Content、IsActive、CanClose、IconSource。LayoutAnchorable:工具視窗 (可停靠/浮動/自動隱藏),如屬性面板、輸出視窗。public static void ChangeTheme(DockingManager dockingManager, ThemeStyle style)
{
Theme theme = null;
switch (style)
{
case ThemeStyle.Blue: theme = new ExpressionBlueTheme(); break;
case ThemeStyle.Black: theme = new ExpressionDarkTheme(); break;
case ThemeStyle.Silver: theme = new ExpressionSilverTheme(); break;
default: theme = new ExpressionBlueTheme(); break;
}
dockingManager.Theme = theme; // 一鍵套用
}
三種主題效果圖**:



<ad:DockingManager x:Name="dockManager" Grid.Row="1">
<ad:DockingManager.Theme>
<ad:ExpressionBlueTheme />
</ad:DockingManager.Theme>
<ad:LayoutRoot>
<ad:LayoutPanel Orientation="Vertical">
<ad:LayoutDocumentPane /> <!-- 動態文檔容器 -->
<ad:LayoutAnchorablePane Name="ToolsPane" DockHeight="150" /> <!-- 工具視窗 -->
</ad:LayoutPanel>
</ad:LayoutRoot>
</ad:DockingManager>
private void CreateFunctionTab(string tabName)
{
// 1. 取得第一個 DocumentPane
var pane = dockManager.Layout.Descendents()
.OfType<LayoutDocumentPane>()
.FirstOrDefault();
if (pane != null)
{
// 2. 建立文檔標籤
var doc = new LayoutDocument
{
Title = tabName,
IsActive = true,
// 3. 載入對應 UserControl (此處示範統一載入 AddUserWindow)
Content = new AddUserWindow()
};
pane.Children.Add(doc); // 加入即顯示
}
}
// Ribbon 按鈕點擊統一入口
private void BtnAddUser_Click(object sender, RoutedEventArgs e)
=> CreateFunctionTab(((Fluent.Button)sender).Header.ToString());
private void BtnModifyUser_Click(object sender, RoutedEventArgs e)
=> CreateFunctionTab(((Fluent.Button)sender).Header.ToString());
private void BtnQueryUser_Click(object sender, RoutedEventArgs e)
=> CreateFunctionTab(((Fluent.Button)sender).Header.ToString());

using Xceed.Wpf.AvalonDock.Layout.Serialization;
// 儲存佈局 (如視窗關閉時)
var serializer = new XmlLayoutSerializer(dockManager);
serializer.Serialize(@".\AvalonDock.config");
// 載入佈局 (應用啟動時)
serializer.Deserialize(@".\AvalonDock.config");
支援記住:文檔順序、作用中標籤、工具視窗停靠位置/大小/自動隱藏狀態。
// 監聽文檔關閉事件
dockManager.DocumentClosing += (s, e) =>
{
var doc = e.Document;
if (doc.Content is IDisposable disposable)
disposable.Dispose(); // 釋放 UserControl 資源
};
| 需求 | API / 屬性 |
|---|---|
| 新增文檔標籤 | pane.Children.Add(new LayoutDocument { Title, Content, IsActive }) |
| 取得作用中文檔 | dockManager.Layout.ActiveDocument |
| 關閉指定文檔 | doc.Close() |
| 遍歷所有文檔 | dockManager.Layout.Descendents().OfType<LayoutDocument>() |
| 動態切換主題 | dockManager.Theme = new ExpressionDarkTheme(); |
| 持久化佈局 | XmlLayoutSerializer.Serialize/Deserialize |