首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 企業級框架實戰(5):Ribbon + AvalonDock 2.0 實現多文檔界面 (MDI) 完整指南 (下)

     編輯:關於.NET

前言

承接上篇靜態佈局,本文實現 動態文檔管理:運行期根據使用者操作 (Ribbon 按鈕、選單) 動態建立、關閉、切換 LayoutDocument,並整合主題動態切換、文檔內容載入、狀態持久化。

核心架構:AvalonDock 2.0 MVVM 化設計

  • DockingManager:核心容器,管理 LayoutRoot → LayoutPanel → LayoutDocumentPane → LayoutDocument 階層。
  • LayoutDocument:單一文檔標籤,支援 Title、Content、IsActive、CanClose、IconSource。
  • LayoutAnchorable:工具視窗 (可停靠/浮動/自動隱藏),如屬性面板、輸出視窗。

動態主題切換:三種 Office 2010 風格

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; // 一鍵套用
}

三種主題效果圖**:

Silver 主題

Blue 主題

Black 主題

XAML:極簡動態佈局 (僅保留 DocumentPane + AnchorablePane)

<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 資源
};

總結:MDI 核心 API 速查

需求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

完整範例原始碼**:TLAgent.SecurityManager.WPF.Avalondock.Demo.rar

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved