### Install Serialization Packages
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/serialization.md
Install the required NuGet packages for XML or JSON serialization support.
```bash
# Install one or both
dotnet add package Dirkster.AvalonDock.Serializer.Xml
dotnet add package Dirkster.AvalonDock.Serializer.Json
```
--------------------------------
### Initialize Project with Dependencies
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/styling-and-theming.md
Commands to create a new WPF project and install the necessary AvalonDock theme packages.
```bash
dotnet new wpf -n ThemeDockApp
cd ThemeDockApp
dotnet add package Dirkster.AvalonDock
dotnet add package Dirkster.AvalonDock.Themes.Arc
dotnet add package Dirkster.AvalonDock.Themes.VS2013
dotnet add package Dirkster.AvalonDock.Themes.VS2010
dotnet add package Dirkster.AvalonDock.Themes.Expression
dotnet add package Dirkster.AvalonDock.Themes.Metro
dotnet add package Dirkster.AvalonDock.Themes.Aero
```
--------------------------------
### Install Optional Packages
Source: https://github.com/dirkster99/avalondock/blob/master/docs/getting-started/installation.md
Commands for installing additional functionality packages for advanced scenarios.
```bash
dotnet add package Dirkster.AvalonDock.Serializer.Xml
dotnet add package Dirkster.AvalonDock.Serializer.Json
dotnet add package Dirkster.AvalonDock.Mvvm
dotnet add package Dirkster.AvalonDock.Mvvm.CommunityToolkit
dotnet add package Dirkster.AvalonDock.DependencyInjection
```
--------------------------------
### Install Expression Theme package
Source: https://github.com/dirkster99/avalondock/blob/master/docs/themes/expression.md
Use the .NET CLI to add the theme package to your project.
```bash
dotnet add package Dirkster.AvalonDock.Themes.Expression
```
--------------------------------
### Install Theme Package
Source: https://github.com/dirkster99/avalondock/blob/master/docs/themes/index.md
Use the .NET CLI to add the specific theme NuGet package to your project.
```bash
dotnet add package Dirkster.AvalonDock.Themes.Arc
```
--------------------------------
### Verify Installation in XAML
Source: https://github.com/dirkster99/avalondock/blob/master/docs/getting-started/installation.md
Add the AvalonDock namespace and DockingManager to your Window to verify the installation.
```xml
```
--------------------------------
### Initialize WPF Project with AvalonDock Dependencies
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/mvvm-ide.md
Create a new WPF project and install the necessary AvalonDock and CommunityToolkit NuGet packages.
```bash
dotnet new wpf -n MvvmIdeApp
cd MvvmIdeApp
dotnet add package Dirkster.AvalonDock
dotnet add package Dirkster.AvalonDock.Mvvm
dotnet add package Dirkster.AvalonDock.Mvvm.CommunityToolkit
dotnet add package Dirkster.AvalonDock.DependencyInjection
dotnet add package Dirkster.AvalonDock.Themes.Arc
dotnet add package CommunityToolkit.Mvvm
```
--------------------------------
### Build AvalonDock Project
Source: https://github.com/dirkster99/avalondock/blob/master/CONTRIBUTING.md
Use this command to build the entire AvalonDock solution. Ensure you have the .NET SDK installed.
```bash
dotnet build source/AvalonDock.sln
```
--------------------------------
### Install VS2013 Theme Package
Source: https://github.com/dirkster99/avalondock/blob/master/docs/themes/vs2013.md
Use the .NET CLI to add the theme package to your project.
```bash
dotnet add package Dirkster.AvalonDock.Themes.VS2013
```
--------------------------------
### Install AvalonDock VS Theme package
Source: https://github.com/dirkster99/avalondock/blob/master/docs/themes/vs.md
Use the .NET CLI to add the theme package to your project.
```bash
dotnet add package Dirkster.AvalonDock.Themes.VS
```
--------------------------------
### Install AvalonDock Packages
Source: https://github.com/dirkster99/avalondock/blob/master/README.md
Use these commands to install the necessary NuGet packages for AvalonDock, including MVVM support and dependency injection.
```bash
dotnet add package Dirkster.AvalonDock
dotnet add package Dirkster.AvalonDock.Mvvm
dotnet add package Dirkster.AvalonDock.Mvvm.CommunityToolkit # optional, for [ObservableProperty] support
dotnet add package Dirkster.AvalonDock.DependencyInjection
dotnet add package Dirkster.AvalonDock.Themes.Arc
```
--------------------------------
### Install MahApps.Metro package
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/styling-and-theming.md
Adds the MahApps.Metro NuGet package to the project.
```bash
dotnet add package MahApps.Metro
```
--------------------------------
### Install Core Package via NuGet
Source: https://github.com/dirkster99/avalondock/blob/master/docs/getting-started/installation.md
Commands to install the core AvalonDock framework using different package management tools.
```bash
dotnet add package Dirkster.AvalonDock
```
```powershell
Install-Package Dirkster.AvalonDock
```
```xml
```
--------------------------------
### Install AvalonDock Dependency Injection package
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/dependency-injection.md
Use the .NET CLI to add the required package to your project.
```bash
dotnet add package Dirkster.AvalonDock.DependencyInjection
```
--------------------------------
### Install AvalonDock MVVM packages
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/mvvm.md
Install the core MVVM and dependency injection packages to enable MVVM support in your project.
```bash
dotnet add package Dirkster.AvalonDock.Mvvm
dotnet add package Dirkster.AvalonDock.DependencyInjection
```
--------------------------------
### Install AvalonDock Themes
Source: https://github.com/dirkster99/avalondock/blob/master/docs/getting-started/installation.md
Commands to install various built-in theme packages for AvalonDock.
```bash
# Modern Arc theme (recommended)
dotnet add package Dirkster.AvalonDock.Themes.Arc
# Visual Studio themes built from .vstheme files (VS2015, VS2022 and VS2026 variants)
dotnet add package Dirkster.AvalonDock.Themes.VS
# Visual Studio 2013 theme
dotnet add package Dirkster.AvalonDock.Themes.VS2013
# Other themes
dotnet add package Dirkster.AvalonDock.Themes.VS2010
dotnet add package Dirkster.AvalonDock.Themes.Expression
dotnet add package Dirkster.AvalonDock.Themes.Metro
dotnet add package Dirkster.AvalonDock.Themes.Aero
```
--------------------------------
### Install theme packages
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/theming.md
Use the .NET CLI to add the required NuGet packages for specific AvalonDock themes.
```bash
dotnet add package Dirkster.AvalonDock.Themes.Arc
```
```bash
dotnet add package Dirkster.AvalonDock.Themes.VS2013
```
```bash
dotnet add package Dirkster.AvalonDock.Themes.VS2010
```
```bash
dotnet add package Dirkster.AvalonDock.Themes.Expression
```
```bash
dotnet add package Dirkster.AvalonDock.Themes.Metro
```
```bash
dotnet add package Dirkster.AvalonDock.Themes.Aero
```
--------------------------------
### Install AvalonDock NuGet Packages
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/layout-persistence.md
Add the required AvalonDock and serializer packages to your project via the .NET CLI.
```bash
dotnet add package Dirkster.AvalonDock
dotnet add package Dirkster.AvalonDock.Serializer.Xml
# Or for JSON:
# dotnet add package Dirkster.AvalonDock.Serializer.Json
```
--------------------------------
### Install AvalonDock Packages
Source: https://github.com/dirkster99/avalondock/blob/master/docs/getting-started/quick-start.md
Add the core AvalonDock library and the Arc theme package to the project.
```bash
dotnet add package Dirkster.AvalonDock
dotnet add package Dirkster.AvalonDock.Themes.Arc
```
--------------------------------
### Install CommunityToolkit MVVM integration
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/mvvm.md
Install this package to use CommunityToolkit.Mvvm source generators with AvalonDock base classes.
```bash
dotnet add package Dirkster.AvalonDock.Mvvm.CommunityToolkit
```
--------------------------------
### Install JSON Serializer Package
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/layout-persistence.md
Add the required NuGet package to your project to enable JSON serialization support.
```bash
dotnet add package Dirkster.AvalonDock.Serializer.Json
```
--------------------------------
### Configure AvalonDock v5 Architecture
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/mvvm-ide.md
Shows the composition root setup for AvalonDock, including service registration and toolbox configuration.
```csharp
App.xaml.cs (Composition Root)
├── AddDockLayoutService(dock => { ← single entry point for dock configuration
│ dock.ConfigureToggleDock(...) ← configures sidebar button size, dock sizes
│ dock.AddToolbox() ← registers tool VMs
│ dock.AddToolbox()
│ dock.AddToolbox()
│ })
└── AddSingleton() ← receives IDockLayoutService via DI
MainViewModel
├── DockLayout (IRootDock) ← bound to ToggleDockingManager.DockLayout
├── OpenFile() → _dockService.OpenOrActivateDocument(...)
└── CloseDocument() → _dockService.CloseDocument(...)
ToggleDockingManager (XAML)
├── DockLayout="{Binding DockLayout}" ← drives the entire layout from the VM
├── DataTemplates per VM type ← renders each toolbox/document
└── PanesStyleSelector ← binds Title, ContentId, IconSource
```
--------------------------------
### Create a Toolbox View Model
Source: https://github.com/dirkster99/avalondock/blob/master/README.md
Examples of defining a toolbox view model using standard base classes or CommunityToolkit integration.
```csharp
using AvalonDock.Core;
using AvalonDock.Mvvm;
public class ExplorerToolbox : ToolboxBase
{
public ExplorerToolbox()
{
Id = "Explorer";
Title = "Explorer";
Zone = DockZone.LeftTop; // Sidebar placement zone
IsOpenByDefault = true; // Open when app starts
ToolTipText = "Solution Explorer";
}
}
```
```csharp
using AvalonDock.Core;
using AvalonDock.Mvvm.CommunityToolkit;
using CommunityToolkit.Mvvm.ComponentModel;
public partial class ExplorerToolbox : ObservableToolboxBase
{
[ObservableProperty] private string _searchFilter = string.Empty;
public ExplorerToolbox()
{
Id = "Explorer";
Title = "Explorer";
Zone = DockZone.LeftTop;
IsOpenByDefault = true;
ToolTipText = "Solution Explorer";
}
}
```
--------------------------------
### Implement Save-on-Close Logic
Source: https://github.com/dirkster99/avalondock/blob/master/docs/api-reference/events.md
This example implements a common save-on-close pattern for documents. It checks if a document is dirty, prompts the user to save, and then either saves or closes the document based on the user's choice.
```csharp
dockManager.DocumentClosing += async (sender, args) =>
{
if (args.Document.Content is IDocument doc && doc.IsDirty)
{
args.Cancel = true; // Prevent immediate close
var result = await ShowSaveDialogAsync(doc);
if (result != SaveResult.Cancel)
{
if (result == SaveResult.Save)
await doc.SaveAsync();
args.Document.Close(); // Close after handling
}
}
};
```
--------------------------------
### Create Custom Theme Resource Dictionary
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/custom-themes.md
Define custom brushes in a XAML resource dictionary. This example merges an existing theme and provides a placeholder for overriding specific brushes.
```xml
```
--------------------------------
### Run a sample project
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/index.md
Use the dotnet CLI to execute a specific sample project from the source directory.
```bash
cd source
dotnet run --project MVVMTestApp
```
--------------------------------
### Create a WPF Project
Source: https://github.com/dirkster99/avalondock/blob/master/docs/getting-started/quick-start.md
Initialize a new WPF application targeting .NET 9.
```bash
dotnet new wpf -n MyDockingApp --framework net9.0-windows
cd MyDockingApp
```
--------------------------------
### Configure Startup Visibility
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/toggle-docking-manager.md
Registers a toolbox with the layout service via dependency injection.
```csharp
services.AddDockLayoutService(dock => dock.AddToolbox());
// ExplorerToolbox sets IsOpen = true in its constructor: it is showing once the window loads.
```
--------------------------------
### Build and Test AvalonDock from Source
Source: https://github.com/dirkster99/avalondock/blob/master/README.md
Use these commands to restore dependencies, build the solution in Release configuration, and run tests.
```bash
dotnet restore source/AvalonDock.sln
dotnet build source/AvalonDock.sln --configuration Release --no-restore
dotnet test source/AvalonDock.sln --configuration Release --no-restore -m:1
```
--------------------------------
### Integrate DI in WPF App Startup
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/dependency-injection.md
Configure services and manually instantiate the MainWindow to support dependency injection. Ensure StartupUri is removed from App.xaml.
```csharp
public partial class App : Application
{
private IServiceProvider? _serviceProvider;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
var mainWindow = _serviceProvider.GetRequiredService();
mainWindow.Show();
}
protected override void OnExit(ExitEventArgs e)
{
(_serviceProvider as IDisposable)?.Dispose();
base.OnExit(e);
}
}
```
--------------------------------
### Configure DockingManager in C#
Source: https://github.com/dirkster99/avalondock/blob/master/docs/api-reference/docking-manager.md
Demonstrates programmatic initialization of the DockingManager, including theme assignment, event subscription for document closing, and layout construction.
```csharp
// Create and configure a DockingManager
var dockManager = new DockingManager();
// Set theme
dockManager.Theme = new ArcDarkTheme();
// Handle document closing
dockManager.DocumentClosing += (sender, args) =>
{
if (args.Document.Content is IModified modified && modified.HasChanges)
{
var result = MessageBox.Show(
"Save changes?", "Confirm",
MessageBoxButton.YesNoCancel);
if (result == MessageBoxResult.Cancel)
args.Cancel = true;
}
};
// Set the layout
dockManager.Layout = new LayoutRoot
{
RootPanel = new LayoutPanel(new LayoutDocumentPane())
};
```
--------------------------------
### IndexOf
Source: https://github.com/dirkster99/avalondock/wiki/LayoutDocumentPane
Gets the index of the specified child content within the LayoutDocumentPane.
```APIDOC
## IndexOf
### Description
Gets the index of the specified child content.
### Method
(Implicitly a method call on a LayoutDocumentPane object)
### Parameters
* **content** (LayoutContent) - The child content to find the index of.
### Returns
(int) The index of the child content, or -1 if not found.
```
--------------------------------
### Track Active Dockable
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/dependency-injection-app.md
Get or set the currently active dockable item.
```csharp
var active = _dockService.ActiveDockable;
_dockService.ActiveDockable = someDocument;
```
--------------------------------
### Configure DI Composition Root in App.xaml.cs
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/mvvm-ide.md
Registers services, configures dock layout options, and initializes the main window via dependency injection.
```csharp
using System.Windows;
using AvalonDock.Core;
using AvalonDock.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using MvvmIdeApp.ViewModels;
namespace MvvmIdeApp;
public partial class App : Application
{
private IServiceProvider? _serviceProvider;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
var mainWindow = _serviceProvider.GetRequiredService();
mainWindow.Show();
}
private static void ConfigureServices(IServiceCollection services)
{
// Configure dock layout: toggle dock options + toolboxes in one call
services.AddDockLayoutService(dock =>
{
dock.ConfigureToggleDock(opts =>
{
opts.ButtonSize = 28;
opts.DefaultDockWidth = 280;
opts.DefaultDockHeight = 220;
});
// Register toolbox VMs — order determines sidebar button order
dock.AddToolbox();
dock.AddToolbox();
dock.AddToolbox();
});
// Main view model — receives IDockLayoutService
services.AddSingleton();
// Main window — receives MainViewModel + ToggleDockOptions
services.AddSingleton();
}
protected override void OnExit(ExitEventArgs e)
{
(_serviceProvider as IDisposable)?.Dispose();
base.OnExit(e);
}
}
```
--------------------------------
### IDropTarget Type Property
Source: https://github.com/dirkster99/avalondock/wiki/IDropTarget
Gets the type of the drop target. This property is read-only.
```csharp
DropTargetType Type { get; }
```
--------------------------------
### Build the Solution
Source: https://github.com/dirkster99/avalondock/blob/master/AGENTS.md
Restores and builds the solution in Release configuration with warnings treated as errors.
```powershell
dotnet restore source/AvalonDock.sln
dotnet build source/AvalonDock.sln --configuration Release --no-restore --warnaserror
```
--------------------------------
### Wire up MainWindow code-behind
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/mvvm-ide.md
Injects the view model and dock options into the MainWindow constructor to initialize the DataContext and apply layout configurations.
```csharp
using System.Windows;
using AvalonDock.DependencyInjection;
using MvvmIdeApp.ViewModels;
namespace MvvmIdeApp;
public partial class MainWindow : Window
{
public MainWindow(MainViewModel viewModel, ToggleDockOptions? dockOptions = null)
{
DataContext = viewModel;
InitializeComponent();
// Apply DI-configured dock options
if (dockOptions != null)
{
dockManager.ButtonSize = dockOptions.ButtonSize;
dockManager.DefaultDockWidth = dockOptions.DefaultDockWidth;
dockManager.DefaultDockHeight = dockOptions.DefaultDockHeight;
}
}
private void OnExit(object sender, RoutedEventArgs e) => Close();
}
```
--------------------------------
### Configure DockOptions in MainWindow
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/dependency-injection-app.md
Applies dock configuration settings during MainWindow initialization via constructor injection.
```csharp
public partial class MainWindow : Window
{
public MainWindow(MainViewModel viewModel, ToggleDockOptions? dockOptions = null)
{
DataContext = viewModel;
InitializeComponent();
if (dockOptions != null)
{
dockManager.ButtonSize = dockOptions.ButtonSize;
dockManager.DefaultDockWidth = dockOptions.DefaultDockWidth;
dockManager.DefaultDockHeight = dockOptions.DefaultDockHeight;
dockManager.ShowHeaderMinimizeButton = dockOptions.ShowHeaderMinimizeButton;
dockManager.ShowHeaderOptionsButton = dockOptions.ShowHeaderOptionsButton;
if (Enum.TryParse(dockOptions.LayoutPriority, out var priority))
{
dockManager.LayoutPriority = priority;
}
}
}
}
```
--------------------------------
### Build and Test AvalonDock
Source: https://github.com/dirkster99/avalondock/blob/master/docs/contributing.md
Clone the repository, navigate to the directory, and build the solution. Run tests with the single-threaded option due to WPF STA requirements.
```bash
git clone https://github.com/Dirkster99/AvalonDock.git
cd AvalonDock
dotnet build source/AvalonDock.sln
dotnet test source/AvalonDock.sln -m:1
```
--------------------------------
### Get Child Index - ILayoutGroup
Source: https://github.com/dirkster99/avalondock/wiki/ILayoutGroup
Determines the index of a given ILayoutElement within the children collection of an ILayoutGroup.
```C#
int IndexOfChild( ILayoutElement element );
```
--------------------------------
### Run the AvalonDock project
Source: https://github.com/dirkster99/avalondock/blob/master/docs/getting-started/quick-start.md
Executes the application using the .NET CLI to verify the docking layout functionality.
```bash
dotnet run
```
--------------------------------
### Get IsVisible Property
Source: https://github.com/dirkster99/avalondock/wiki/ILayoutPanelElement
Access the IsVisible property to determine if a layout element is currently visible. This is a read-only property.
```C#
bool IsVisible { get; }
```
--------------------------------
### Build AvalonDock Solution
Source: https://github.com/dirkster99/avalondock/blob/master/docs/getting-started/building-from-source.md
Compile the entire AvalonDock solution using the .NET CLI. Ensure all warnings are resolved as they are treated as errors.
```bash
dotnet build source/AvalonDock.sln
```
--------------------------------
### Interact with DockingManager in C#
Source: https://github.com/dirkster99/avalondock/blob/master/docs/concepts/architecture.md
Demonstrates accessing the layout tree, updating themes at runtime, and querying specific anchorables by ID.
```csharp
// Access the layout
LayoutRoot layout = dockManager.Layout;
// Change theme at runtime
dockManager.Theme = new ArcLightTheme();
// Find a specific anchorable
var explorer = layout.Descendents()
.OfType()
.FirstOrDefault(a => a.ContentId == "explorer");
```
--------------------------------
### Get and Set Orientation Property
Source: https://github.com/dirkster99/avalondock/wiki/ILayoutOrientableGroup
This property determines the orientation of the content displayed within the interface of the object that implements ILayoutOrientableGroup. It can be read and modified.
```csharp
Orientation Orientation { get; set; }
```
--------------------------------
### Apply DictionaryTheme in Code
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/custom-themes.md
Instantiate a `DictionaryTheme` with a custom resource dictionary and assign it to the DockingManager. Ensure the resource dictionary path is correct.
```csharp
var resourceDict = new ResourceDictionary
{
Source = new Uri("pack://application:,,,/MyApp;component/Themes/MyCustomTheme.xaml")
};
dockManager.Theme = new DictionaryTheme(resourceDict);
```
--------------------------------
### GetTargets
Source: https://github.com/dirkster99/avalondock/wiki/IOverlayWindow
Gets all IDropTarget areas in which a given floating element can be dropped into this window. The emitted information is used to draw the preview elements to show each drop target and realize the drop itself when the drag operation ends at a given drop target.
```APIDOC
## GetTargets
### Description
Gets all [[IDropTarget]] areas in which a given floating element can be dropped into this window. The emitted information is used to draw the preview elements to show each drop target and realize the drop itself when the drag operation ends at a given drop target.
### Method Signature
```csharp
IEnumerable IOverlayWindow.GetTargets()
```
```
--------------------------------
### Configure AvalonDock in App.xaml.cs
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/dependency-injection-app.md
Sets up the service provider and registers AvalonDock services, toolboxes, and view models within the application startup lifecycle.
```csharp
using System;
using System.Windows;
using AvalonDock.Core;
using AvalonDock.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using MyApp.ViewModels;
namespace MyApp;
public partial class App : Application
{
private IServiceProvider? _serviceProvider;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
var mainWindow = _serviceProvider.GetRequiredService();
mainWindow.Show();
}
private static void ConfigureServices(IServiceCollection services)
{
// Configure dock layout: toggle dock options + toolboxes in one call
services.AddDockLayoutService(dock =>
{
dock.ConfigureToggleDock(opts =>
{
opts.ButtonSize = 28;
opts.DefaultDockWidth = 280;
opts.DefaultDockHeight = 220;
opts.LayoutPriority = nameof(DockLayoutPriority.BottomFullWidth);
});
// Register toolbox VMs — order determines sidebar button order
dock.AddToolbox();
dock.AddToolbox();
dock.AddToolbox();
dock.AddToolbox();
dock.AddToolbox();
});
// MainViewModel receives IDockLayoutService
services.AddSingleton();
// MainWindow receives MainViewModel + ToggleDockOptions
services.AddSingleton();
}
protected override void OnExit(ExitEventArgs e)
{
(_serviceProvider as IDisposable)?.Dispose();
base.OnExit(e);
}
}
```
--------------------------------
### Configure MainWindow XAML Layout
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/mvvm-ide.md
Sets up DataTemplates for view models and configures the ToggleDockingManager with the custom style selector.
```xml
```
--------------------------------
### Configure MainWindow XAML
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/styling-and-theming.md
Define the DockingManager and a ComboBox for theme selection within the main window layout.
```xml
```
--------------------------------
### Create MainViewModel
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/mvvm-ide.md
Implements the main view model using IDockLayoutService for layout management and document lifecycle control.
```csharp
using AvalonDock.Core;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace MvvmIdeApp.ViewModels;
public partial class MainViewModel : ObservableObject
{
private readonly IDockLayoutService _dockService;
/// The MVVM layout tree — bind to DockLayout on the DockingManager.
public IRootDock DockLayout => _dockService.Layout;
/// Typed access to the Explorer toolbox via the layout service.
public ExplorerToolbox? Explorer => _dockService.GetAnchorable();
/// Typed access to the Output toolbox.
public OutputToolbox? Output => _dockService.GetAnchorable();
public MainViewModel(IDockLayoutService dockService)
{
_dockService = dockService;
// Wire up file-open callback from Explorer
Explorer?.SetOpenFileCallback(OpenFile);
Output?.AppendLine("Application initialized via DI.");
}
/// Opens a file as a document tab, or activates it if already open.
public void OpenFile(string filePath)
{
_dockService.OpenOrActivateDocument(
existing => existing.FilePath == filePath, // find existing
() => // or create new
{
var tab = new EditorTabViewModel();
tab.LoadFile(filePath);
return tab;
});
Output?.AppendLine($"Opened: {filePath}");
}
[RelayCommand]
private void CloseDocument(EditorTabViewModel? tab)
{
if (tab != null)
{
_dockService.CloseDocument(tab);
Output?.AppendLine($"Closed: {tab.Title}");
}
}
}
```
--------------------------------
### Open and Activate Documents with IDockLayoutService
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/dependency-injection-app.md
Use OpenDocument for new tabs and OpenOrActivateDocument to find existing tabs by predicate or create them via a factory.
```csharp
// Open a new document
_dockService.OpenDocument(new EditorTabViewModel { Title = "new.cs" });
// Open or activate an existing document
_dockService.OpenOrActivateDocument(
existing => existing.FilePath == filePath, // Find predicate
() => // Factory if not found
{
var tab = new EditorTabViewModel();
tab.LoadFile(filePath);
return tab;
});
```
--------------------------------
### Register Toolboxes with DI
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/toggle-docking-manager.md
Adds multiple toolboxes to the dock layout service during application startup.
```csharp
services.AddDockLayoutService(dock =>
{
dock.AddToolbox();
dock.AddToolbox();
dock.AddToolbox();
});
```
--------------------------------
### Define Theme Options in C#
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/styling-and-theming.md
Create a helper class to map theme names to their respective AvalonDock theme instances.
```csharp
using AvalonDock.Themes;
namespace ThemeDockApp;
public class ThemeOption
{
public string Name { get; init; }
public Theme Theme { get; init; }
public override string ToString() => Name;
public static ThemeOption[] All => new[]
{
new ThemeOption { Name = "Arc Dark", Theme = new ArcDarkTheme() },
new ThemeOption { Name = "Arc Light", Theme = new ArcLightTheme() },
new ThemeOption { Name = "VS2013 Dark", Theme = new Vs2013DarkTheme() },
new ThemeOption { Name = "VS2013 Light", Theme = new Vs2013LightTheme() },
new ThemeOption { Name = "VS2013 Blue", Theme = new Vs2013BlueTheme() },
new ThemeOption { Name = "VS2010", Theme = new VS2010Theme() },
new ThemeOption { Name = "Metro", Theme = new MetroTheme() },
new ThemeOption { Name = "Aero", Theme = new AeroTheme() },
new ThemeOption { Name = "Generic", Theme = new GenericTheme() },
};
}
```
--------------------------------
### Navigate Layout Tree from Code
Source: https://github.com/dirkster99/avalondock/blob/master/docs/concepts/layout-model.md
Demonstrates how to access and traverse the layout tree from C# code to find specific layout elements like documents or anchorables.
```csharp
LayoutRoot layout = dockManager.Layout;
// Find all documents
var documents = layout.Descendents()
.OfType()
.ToList();
// Find a specific anchorable by ContentId
var explorer = layout.Descendents()
.OfType()
.FirstOrDefault(a => a.ContentId == "explorer");
// Iterate children of a panel
foreach (var child in layout.RootPanel.Children)
{
// Process each child
}
```
--------------------------------
### Implement the Theme Class
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/styling-and-theming.md
Create a C# class inheriting from AvalonDock.Themes.Theme to provide the URI for the custom resource dictionary.
```csharp
using System;
using AvalonDock.Themes;
namespace ThemeDockApp.Themes;
public class CorporateTheme : Theme
{
public override Uri GetResourceUri()
{
return new Uri(
"/ThemeDockApp;component/Themes/CorporateTheme.xaml",
UriKind.Relative);
}
}
```
--------------------------------
### Apply Arc Light Theme (C#)
Source: https://github.com/dirkster99/avalondock/blob/master/docs/themes/arc.md
Instantiate and assign the ArcLightTheme to the DockManager in C#.
```csharp
dockManager.Theme = new ArcLightTheme();
```
--------------------------------
### Implement Custom Layout Engine
Source: https://github.com/dirkster99/avalondock/blob/master/docs/migration/index.md
Implement the ILayoutEngine interface to replace previous internal or reflection-based layout calculation logic.
```csharp
public class MyLayoutEngine : ILayoutEngine
{
// Implement the required layout calculation methods
}
```
--------------------------------
### Apply DictionaryTheme for resource overrides
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/styling-and-theming.md
Wraps a ResourceDictionary as a theme for quick experiments or external file loading.
```csharp
var overrides = new ResourceDictionary
{
Source = new Uri("pack://application:,,,/ThemeDockApp;component/Themes/BrandOverrides.xaml")
};
dockManager.Theme = new DictionaryTheme(overrides);
```
--------------------------------
### Import theme brush resources
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/theming.md
Merge theme-specific resource dictionaries into your application to maintain visual consistency.
```xml
```
--------------------------------
### Register Basic Toolbox
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/dependency-injection-app.md
Registers a toolbox with a parameterless constructor as a singleton.
```csharp
services.AddDockLayoutService(dock =>
{
dock.AddToolbox();
});
```
--------------------------------
### Load custom .vstheme files
Source: https://github.com/dirkster99/avalondock/blob/master/docs/themes/vs.md
Load themes from file paths, streams, or byte arrays. The stream constructor automatically detects gzip compression.
```csharp
dockManager.Theme = new VsTheme("path/to/custom.vstheme");
```
```csharp
using var stream = File.OpenRead("custom.vstheme");
dockManager.Theme = new VsTheme(stream);
```
```csharp
byte[] gzipBytes = VsThemeResourceLoader.Load(
Assembly.GetExecutingAssembly(),
"MyApp.Resources.mytheme.vstheme.gz");
dockManager.Theme = new VsTheme(gzipBytes);
```
```csharp
var palette = VsThemeParser.ParseFile("custom.vstheme");
dockManager.Theme = new VsTheme(palette);
```
--------------------------------
### Configure ToggleDockingManager in Code-Behind
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/toggle-docking-manager.md
Set sizing and layout priority properties for the docking manager programmatically.
```csharp
dockManager.ButtonSize = 28;
dockManager.DefaultDockWidth = 280;
dockManager.DefaultDockHeight = 220;
dockManager.LayoutPriority = DockLayoutPriority.BottomFullWidth;
```
--------------------------------
### Implement IToolbox
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/toggle-docking-manager.md
Defines a toolbox view model by inheriting from ToolboxBase and setting properties like Zone and IsOpenByDefault.
```csharp
public class ExplorerToolbox : ToolboxBase
{
public ExplorerToolbox()
{
Id = "Explorer";
Title = "Explorer";
Zone = DockZone.LeftTop;
IsOpenByDefault = true;
ToolTipText = "Explorer";
Shortcut = "Ctrl+Shift+E";
Icon = myExplorerIcon; // ImageSource, UIElement, or DrawingImage
}
}
```
--------------------------------
### Implement Theme Switching in MainWindow.xaml.cs
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/styling-and-theming.md
Populate the theme selector and handle selection changes to update the DockManager theme dynamically.
```csharp
using System.Windows;
using System.Windows.Controls;
namespace ThemeDockApp;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// Populate the theme selector
ThemeSelector.ItemsSource = ThemeOption.All;
ThemeSelector.SelectedIndex = 0; // Arc Dark
}
private void ThemeSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ThemeSelector.SelectedItem is ThemeOption option)
{
DockManager.Theme = option.Theme;
}
}
}
```
--------------------------------
### Update App.xaml for DI
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/mvvm-ide.md
Removes the StartupUri to allow the application window to be managed by the DI container.
```xml
```
--------------------------------
### Inject Options into MainWindow
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/dependency-injection.md
Use constructor injection to pass view models and dock options to the MainWindow.
```csharp
public partial class MainWindow : Window
{
public MainWindow(MainViewModel viewModel, ToggleDockOptions? dockOptions = null)
{
DataContext = viewModel;
InitializeComponent();
if (dockOptions != null)
{
dockManager.ButtonSize = dockOptions.ButtonSize;
dockManager.DefaultDockWidth = dockOptions.DefaultDockWidth;
dockManager.DefaultDockHeight = dockOptions.DefaultDockHeight;
dockManager.ShowHeaderMinimizeButton = dockOptions.ShowHeaderMinimizeButton;
dockManager.ShowHeaderOptionsButton = dockOptions.ShowHeaderOptionsButton;
if (Enum.TryParse(dockOptions.LayoutPriority, out var priority))
dockManager.LayoutPriority = priority;
}
}
}
```
--------------------------------
### Configure Floating and Detached Windows via Dependency Injection
Source: https://github.com/dirkster99/avalondock/blob/master/docs/concepts/floating-windows.md
Apply floating and detached window settings during the service registration process.
```csharp
services.AddDockLayoutService(dock =>
{
dock.AddToolbox();
dock.ConfigureDocking(o =>
{
o.AllowFloatingWindows = false;
o.AllowDetachedWindows = false;
});
});
```
--------------------------------
### Use IDockLayoutService
Source: https://github.com/dirkster99/avalondock/blob/master/docs/guides/mvvm.md
Inject IDockLayoutService into your ViewModel to manage layout state and open or activate documents programmatically.
```csharp
using AvalonDock.Core;
using CommunityToolkit.Mvvm.ComponentModel;
public partial class MainViewModel : ObservableObject
{
private readonly IDockLayoutService _dockService;
// Bind to ToggleDockingManager.DockLayout
public IRootDock DockLayout => _dockService.Layout;
// Typed access to toolboxes
public ExplorerToolbox? Explorer => _dockService.GetAnchorable();
public MainViewModel(IDockLayoutService dockService)
{
_dockService = dockService;
}
public void OpenFile(string path)
{
_dockService.OpenOrActivateDocument(
existing => existing.FilePath == path,
() => { var tab = new EditorTab(); tab.LoadFile(path); return tab; });
}
}
```
--------------------------------
### Implement Serialization in MainWindow Code-Behind
Source: https://github.com/dirkster99/avalondock/blob/master/docs/tutorials/layout-persistence.md
Handles the actual XML serialization and deserialization using the DockingManager reference. The LayoutSerializationCallback must be configured to return view models instead of UI controls.
```csharp
using AvalonDock.Serializer.Xml;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += OnLoaded;
Closing += OnWindowClosing;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (DataContext is WorkspaceViewModel vm)
{
// Wire up layout callbacks
vm.OnSaveLayout = SaveLayout;
vm.OnRestoreLayout = path => RestoreLayout(path, vm);
vm.OnResetLayout = () =>
{
// Remove and re-add the DockingManager to reset
// Or simply delete the layout file and restart
};
// Auto-restore on startup
RestoreLayout(WorkspaceViewModel.LayoutFilePath, vm);
}
}
private void OnWindowClosing(object sender, CancelEventArgs e)
{
SaveLayout(WorkspaceViewModel.LayoutFilePath);
}
private void SaveLayout(string path)
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
var serializer = new XmlLayoutSerializer(DockManager);
using var writer = new StreamWriter(path);
serializer.Serialize(writer);
}
private void RestoreLayout(string path, WorkspaceViewModel vm)
{
if (!File.Exists(path)) return;
var serializer = new XmlLayoutSerializer(DockManager);
serializer.LayoutSerializationCallback += (sender, args) =>
{
// Match by ContentId and return the VIEW MODEL (not a control)
var contentId = args.Model.ContentId;
// Try to find among existing tool view models
var tool = vm.Tools.FirstOrDefault(t => t.ContentId == contentId);
if (tool != null)
{
args.Content = tool;
return;
}
// Try to find among existing documents
var doc = vm.Documents.FirstOrDefault(d => d.ContentId == contentId);
if (doc != null)
{
args.Content = doc;
return;
}
// Unknown content — skip it
args.Cancel = true;
};
using var reader = new StreamReader(path);
serializer.Deserialize(reader);
}
}
```