### 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); } } ```