Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7fa0987
Add canonical ReactiveUI sample app
wieslawsoltes Jan 17, 2026
f1af0a9
Add canonical sample to solution
wieslawsoltes Jan 17, 2026
338b6bf
Update reactiveui canonical sample
wieslawsoltes Jan 17, 2026
570c411
Refine overlays and window routing
wieslawsoltes Jan 17, 2026
1fd64a9
Fix dock close behavior and activation loading
wieslawsoltes Jan 17, 2026
9fc46cc
Fix dialog routing and cleanup
wieslawsoltes Jan 18, 2026
d62b57c
Avoid reloading on tab switch
wieslawsoltes Jan 18, 2026
c4bb88c
Extract overlay services and controls
wieslawsoltes Jan 18, 2026
b7a6268
Add lifecycle and overlay host contracts
wieslawsoltes Jan 20, 2026
8f7a0b4
Add Avalonia overlay controls and themes
wieslawsoltes Jan 20, 2026
99c6d15
Add ReactiveUI overlay services and lifecycle helpers
wieslawsoltes Jan 20, 2026
0c6a5f8
Add ReactiveUI navigation abstractions
wieslawsoltes Jan 20, 2026
736d181
Update canonical sample integration
wieslawsoltes Jan 20, 2026
e00834d
Merge ReactiveUI navigation into services
wieslawsoltes Jan 20, 2026
d80a11c
Fix canonical sample control recycling
wieslawsoltes Jan 20, 2026
c44cd4a
Improve canonical sample host resolution
wieslawsoltes Jan 20, 2026
8c6d761
Add overlay services reference docs
wieslawsoltes Jan 20, 2026
0a65a33
Add overlay customization guide
wieslawsoltes Jan 20, 2026
48fd598
Simplify canonical sample overlay services
wieslawsoltes Jan 20, 2026
05e07d1
Refactor canonical dock roots to overlay provider
wieslawsoltes Jan 20, 2026
9804568
Update canonical view models for overlay provider
wieslawsoltes Jan 20, 2026
672fab6
Scope overlay services per root in sample
wieslawsoltes Jan 21, 2026
acd4978
Guard overlay host reparenting
wieslawsoltes Jan 21, 2026
6ad5b5e
Hide reload when no local busy command
wieslawsoltes Jan 21, 2026
d34983a
Complete confirmation requests on close
wieslawsoltes Jan 21, 2026
41123f4
Remove DI helper project from solution
wieslawsoltes Jan 21, 2026
b94a08b
Inline Dock DI registrations in sample
wieslawsoltes Jan 21, 2026
4c350cb
Update DI docs for manual registration
wieslawsoltes Jan 21, 2026
5f836ee
Reorganize ReactiveUI services folders
wieslawsoltes Jan 21, 2026
a4acec8
Use global usings in canonical sample
wieslawsoltes Jan 21, 2026
59b5bfa
Update overlay services reference
wieslawsoltes Jan 21, 2026
d033030
Add routing, lifecycle, and visual tree tests
wieslawsoltes Jan 21, 2026
563dfdf
Add Avalonia services helpers project
wieslawsoltes Jan 21, 2026
aa1236e
Move DockViewModel into reactive services
wieslawsoltes Jan 21, 2026
03dd52f
Move BusyRootDock and IReloadable into core
wieslawsoltes Jan 21, 2026
ce58c28
Update Dock.Model.ReactiveUI.Services.Avalonia.csproj
wieslawsoltes Jan 21, 2026
39b128c
Update Dock.Model.ReactiveUI.Services.csproj
wieslawsoltes Jan 21, 2026
2b7c232
Update toc.yml
wieslawsoltes Jan 21, 2026
e170efe
Update build-docs.ps1
wieslawsoltes Jan 21, 2026
ecffa7e
Update build-docs.sh
wieslawsoltes Jan 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Dock.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<Project Path="samples/DockMvvmSample/DockMvvmSample.csproj" />
<Project Path="samples/DockPrismSample/DockPrismSample.csproj" />
<Project Path="samples/DockReactivePropertySample/DockReactivePropertySample.csproj" />
<Project Path="samples/DockReactiveUICanonicalSample/DockReactiveUICanonicalSample.csproj" />
<Project Path="samples/DockReactiveUIDiSample/DockReactiveUIDiSample.csproj" />
<Project Path="samples/DockReactiveUIRoutingSample/DockReactiveUIRoutingSample.csproj" />
<Project Path="samples/DockReactiveUISample/DockReactiveUISample.csproj" />
Expand All @@ -75,13 +76,13 @@
<Project Path="src/Dock.MarkupExtension/Dock.MarkupExtension.csproj" />
<Project Path="src/Dock.Model.Avalonia/Dock.Model.Avalonia.csproj" />
<Project Path="src/Dock.Model.CaliburMicro/Dock.Model.CaliburMicro.csproj" />
<Project Path="src/Dock.Model.Extensions.DependencyInjection/Dock.Model.Extensions.DependencyInjection.csproj" />
<Project Path="src/Dock.Model.Inpc/Dock.Model.Inpc.csproj" />
<Project Path="src/Dock.Model.Mvvm/Dock.Model.Mvvm.csproj" />
<Project Path="src/Dock.Model.Prism/Dock.Model.Prism.csproj" />
<Project Path="src/Dock.Model.ReactiveProperty/Dock.Model.ReactiveProperty.csproj" />
<Project Path="src/Dock.Model.ReactiveUI.Navigation/Dock.Model.ReactiveUI.Navigation.csproj" />
<Project Path="src/Dock.Model.ReactiveUI/Dock.Model.ReactiveUI.csproj" />
<Project Path="src/Dock.Model.ReactiveUI.Services/Dock.Model.ReactiveUI.Services.csproj" />
<Project Path="src/Dock.Model.ReactiveUI.Services.Avalonia/Dock.Model.ReactiveUI.Services.Avalonia.csproj" />
<Project Path="src/Dock.Model/Dock.Model.csproj" />
<Project Path="src/Dock.Serializer.Newtonsoft/Dock.Serializer.Newtonsoft.csproj" />
<Project Path="src/Dock.Serializer.Protobuf/Dock.Serializer.Protobuf.csproj" />
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ Model packages:
- `Dock.Model.Prism` - Prism framework integration
- `Dock.Model.Inpc` - INotifyPropertyChanged base implementation
- `Dock.Model.Avalonia` - Avalonia-specific model extensions
- `Dock.Model.Extensions.DependencyInjection` - .NET DI container integration

Serialization packages:
- `Dock.Serializer.Newtonsoft` - JSON serialization using Newtonsoft.Json
Expand Down
2 changes: 2 additions & 0 deletions build-docs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ dotnet tool restore
dotnet build -c Release
dotnet docfx docfx/docfx.json
rm -rf src/Dock.Model.ReactiveUI/Generated
rm -rf src/Dock.Model.ReactiveUI.Services/Generated
rm -rf src/Dock.Model.ReactiveUI.Services.Avalonia/Generated
2 changes: 2 additions & 0 deletions build-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ dotnet build -c Release
dotnet tool restore
dotnet docfx docfx/docfx.json
rm -rf src/Dock.Model.ReactiveUI/Generated
rm -rf src/Dock.Model.ReactiveUI.Services/Generated
rm -rf src/Dock.Model.ReactiveUI.Services.Avalonia/Generated
2 changes: 2 additions & 0 deletions docfx/articles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Choose the implementation that matches your MVVM framework:
- [Programmatic docking](dock-programmatic-docking.md) – Use `DockService` to validate and execute docking operations.
- [Drag actions and modifiers](dock-drag-actions.md) – How modifier keys map to docking actions.
- [Styling and theming](dock-styling.md) – Customize the appearance of Dock controls.
- [Overlay customization](dock-overlay-customization.md) – Customize overlay layers and control themes.
- [DataTemplates and custom dock types](dock-datatemplates.md) – Create custom dock types with their own visual representation.
- [Custom themes](dock-custom-theme.md) – Build and apply your own theme.
- [Context menus](dock-context-menus.md) – Localize or replace built-in menus.
Expand Down Expand Up @@ -99,6 +100,7 @@ Choose the implementation that matches your MVVM framework:
- [Dock settings](dock-settings.md) – Global drag/drop options and thresholds.
- [Dock properties](dock-properties.md) – Use attached properties to mark drag areas and drop targets.
- [DockSettings in controls](dock-settings-controls.md) – Apply global drag/drop settings when writing custom controls.
- [Overlay services and host resolution](dock-overlay-services-reference.md) – Busy/dialog/confirmation services and host lookup flow.

## Samples and additional resources

Expand Down
86 changes: 42 additions & 44 deletions docfx/articles/dock-dependency-injection.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
# Dependency injection

Dock provides an integration library for the default .NET service container. The `Dock.Model.Extensions.DependencyInjection` package exposes an `AddDock` extension for `IServiceCollection`.
Dock does not ship a dedicated dependency injection helper package. Register the core services manually, or copy the `AddDock` helper from `samples/DockReactiveUIDiSample/ServiceCollectionExtensions.cs` into your application.

## Installation

First, install the dependency injection package:

```bash
dotnet add package Dock.Model.Extensions.DependencyInjection
```

Also install your preferred serializer package:
Install your preferred serializer package:

```bash
# Choose one serializer:
Expand All @@ -21,51 +15,52 @@ dotnet add package Dock.Serializer.Xml # XML
dotnet add package Dock.Serializer.Yaml # YAML
```

If you are using the default .NET service container, ensure you have the DI package:

```bash
dotnet add package Microsoft.Extensions.DependencyInjection
```

## Register services

Reference the package and register your factory and serializer types during startup:
Register your factory and serializer types during startup:

```csharp
using Dock.Model.Extensions.DependencyInjection;
using Dock.Model.Core;
using Dock.Serializer; // or your preferred serializer namespace
using Microsoft.Extensions.DependencyInjection;

// Register with JSON serializer (Newtonsoft.Json)
services.AddDock<MyDockFactory, DockSerializer>();

// Or with System.Text.Json serializer
services.AddDock<MyDockFactory, Dock.Serializer.SystemTextJson.DockSerializer>();

// Or with Protobuf serializer
services.AddDock<MyDockFactory, ProtobufDockSerializer>();

// Or with XML serializer
services.AddDock<MyDockFactory, DockXmlSerializer>();
services.AddSingleton<IDockState, DockState>();
services.AddSingleton<MyDockFactory>();
services.AddSingleton<IFactory>(static sp => sp.GetRequiredService<MyDockFactory>());

// Or with YAML serializer
services.AddDock<MyDockFactory, DockYamlSerializer>();
services.AddSingleton<DockSerializer>();
services.AddSingleton<IDockSerializer>(static sp => sp.GetRequiredService<DockSerializer>());
```

This registers `IDockState`, your factory implementation as `IFactory`, and the serializer as `IDockSerializer`.

## Complete example
If you prefer an `AddDock` helper, copy the sample extension from `samples/DockReactiveUIDiSample/ServiceCollectionExtensions.cs`.

Here's a full example showing how to set up dependency injection with Dock:
## Complete example

```csharp
using Microsoft.Extensions.DependencyInjection;
using Dock.Model.Extensions.DependencyInjection;
using Dock.Model.Core;
using Dock.Serializer;
using Microsoft.Extensions.DependencyInjection;

public void ConfigureServices(IServiceCollection services)
{
// Register your view models and views
services.AddTransient<MyDocumentViewModel>();
services.AddTransient<MyToolViewModel>();

// Register Dock services
services.AddDock<MyDockFactory, DockSerializer>();

// Register other application services

services.AddSingleton<IDockState, DockState>();
services.AddSingleton<MyDockFactory>();
services.AddSingleton<IFactory>(static sp => sp.GetRequiredService<MyDockFactory>());

services.AddSingleton<DockSerializer>();
services.AddSingleton<IDockSerializer>(static sp => sp.GetRequiredService<DockSerializer>());

services.AddSingleton<MyApplicationService>();
}
```
Expand All @@ -82,36 +77,39 @@ public class MainWindowViewModel
private readonly IDockSerializer _serializer;

public MainWindowViewModel(
IFactory factory,
IDockState dockState,
IFactory factory,
IDockState dockState,
IDockSerializer serializer)
{
_factory = factory;
_dockState = dockState;
_serializer = serializer;

// Create layout using the factory

Layout = _factory.CreateLayout();
_factory.InitLayout(Layout);
}

public IRootDock Layout { get; }
}
```

## Framework-specific registration

For ReactiveUI applications, you can also register the ReactiveUI-specific factory:
For ReactiveUI applications, register your ReactiveUI factory in the same way:

```csharp
using Dock.Model.Extensions.DependencyInjection;
using Dock.Model.ReactiveUI;
using Dock.Model.Core;
using Dock.Serializer;
using Microsoft.Extensions.DependencyInjection;

services.AddDock<MyReactiveUIFactory, DockSerializer>();
services.AddSingleton<IDockState, DockState>();
services.AddSingleton<MyReactiveUIFactory>();
services.AddSingleton<IFactory>(static sp => sp.GetRequiredService<MyReactiveUIFactory>());

services.AddSingleton<DockSerializer>();
services.AddSingleton<IDockSerializer>(static sp => sp.GetRequiredService<DockSerializer>());
```

Where `MyReactiveUIFactory` derives from `Dock.Model.ReactiveUI.Factory`.

For an overview of all guides see the [documentation index](README.md).


2 changes: 1 addition & 1 deletion docfx/articles/dock-inpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Follow these instructions to create a minimal INPC-based application using Dock.
dotnet add package Dock.Serializer.SystemTextJson # JSON (System.Text.Json)

# For dependency injection:
dotnet add package Dock.Model.Extensions.DependencyInjection
dotnet add package Microsoft.Extensions.DependencyInjection
```

3. **Set up View Locator (Required)**
Expand Down
2 changes: 1 addition & 1 deletion docfx/articles/dock-mvvm.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The following steps walk you through creating a very small application that uses
dotnet add package Dock.Serializer.SystemTextJson # JSON (System.Text.Json)

# For dependency injection:
dotnet add package Dock.Model.Extensions.DependencyInjection
dotnet add package Microsoft.Extensions.DependencyInjection
```

3. **Set up View Locator (Required)**
Expand Down
131 changes: 131 additions & 0 deletions docfx/articles/dock-overlay-customization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Overlay customization guide

This guide explains how to customize the overlay stack and control themes used by `OverlayHost`, including custom layers, order changes, and template overrides.

## Default overlay stack
The Fluent theme ships a default layer collection (`DockDefaultOverlayLayers`) that contains:
- Dialog overlay (ZIndex 10)
- Confirmation overlay (ZIndex 20)
- Busy overlay (ZIndex 30)

Each layer uses a style key from `OverlayLayerStyleKeys` so the control theme can be replaced without changing the layer definition.

## Replace the overlay layer stack
Use a custom `OverlayLayerCollection` to change ordering, input blocking, or the overlay controls used.

```xml
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<OverlayLayerCollection x:Key="MyOverlayLayers" x:Shared="False">
<OverlayLayer ZIndex="5"
BlocksInput="False"
StyleKey="{x:Static OverlayLayerStyleKeys.DialogLayerThemeKey}">
<DialogOverlayControl DialogService="{Binding Dialogs}"
GlobalDialogService="{Binding GlobalDialogService}" />
</OverlayLayer>
<OverlayLayer ZIndex="15"
StyleKey="{x:Static OverlayLayerStyleKeys.ConfirmationLayerThemeKey}">
<ConfirmationOverlayControl ConfirmationService="{Binding Confirmations}"
GlobalConfirmationService="{Binding GlobalConfirmationService}" />
</OverlayLayer>
<OverlayLayer ZIndex="25"
StyleKey="{x:Static OverlayLayerStyleKeys.BusyLayerThemeKey}">
<BusyOverlayControl BusyService="{Binding Busy}"
GlobalBusyService="{Binding GlobalBusyService}" />
</OverlayLayer>
</OverlayLayerCollection>

<ControlTheme x:Key="{x:Type OverlayHost}" TargetType="OverlayHost">
<Setter Property="OverlayLayers" Value="{DynamicResource MyOverlayLayers}" />
</ControlTheme>
</ResourceDictionary>
```

Notes:
- Set `x:Shared="False"` for `OverlayLayerCollection` so each host window gets its own instances.
- `BlocksInput="False"` allows pointer input to pass through when the overlay is visible.

## Add a custom overlay layer
Create a custom overlay control and insert it into the stack with a new `OverlayLayer`.

```xml
<OverlayLayerCollection x:Key="MyOverlayLayers" x:Shared="False">
<OverlayLayer ZIndex="5" BlocksInput="False">
<MyNotificationOverlay IsVisible="{Binding HasNotifications}" />
</OverlayLayer>
<OverlayLayer ZIndex="10"
StyleKey="{x:Static OverlayLayerStyleKeys.DialogLayerThemeKey}">
<DialogOverlayControl DialogService="{Binding Dialogs}"
GlobalDialogService="{Binding GlobalDialogService}" />
</OverlayLayer>
<OverlayLayer ZIndex="20"
StyleKey="{x:Static OverlayLayerStyleKeys.ConfirmationLayerThemeKey}">
<ConfirmationOverlayControl ConfirmationService="{Binding Confirmations}"
GlobalConfirmationService="{Binding GlobalConfirmationService}" />
</OverlayLayer>
<OverlayLayer ZIndex="30"
StyleKey="{x:Static OverlayLayerStyleKeys.BusyLayerThemeKey}">
<BusyOverlayControl BusyService="{Binding Busy}"
GlobalBusyService="{Binding GlobalBusyService}" />
</OverlayLayer>
</OverlayLayerCollection>
```

## Override overlay control themes
You can replace the control templates or update visuals via `ControlTheme` resources. The overlay layers reference these keys:
- `OverlayLayerStyleKeys.BusyLayerThemeKey`
- `OverlayLayerStyleKeys.DialogLayerThemeKey`
- `OverlayLayerStyleKeys.ConfirmationLayerThemeKey`

Example: override the busy overlay theme.

```xml
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Static OverlayLayerStyleKeys.BusyLayerThemeKey}"
TargetType="BusyOverlayControl"
BasedOn="{StaticResource {x:Type BusyOverlayControl}}">
<Setter Property="Template">
<ControlTemplate>
<!-- Custom template markup here. -->
</ControlTemplate>
</Setter>
</ControlTheme>
</ResourceDictionary>
```

## Replace dialog and confirmation shells
Dialog overlays use data templates defined in `OverlayDataTemplates.axaml`. Override them by replacing the resource keys:
- `DockDialogRequestTemplate`
- `DockConfirmationRequestTemplate`

```xml
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:services="using:Dock.Model.Services">
<DataTemplate x:Key="DockDialogRequestTemplate" DataType="services:DialogRequest">
<MyDialogShell Title="{Binding Title}" Content="{Binding Content}" />
</DataTemplate>
<DataTemplate x:Key="DockConfirmationRequestTemplate" DataType="services:ConfirmationRequest">
<MyConfirmationShell Title="{Binding Title}" Message="{Binding Message}" />
</DataTemplate>
</ResourceDictionary>
```

## DI-based overlay layer registration
If you want to resolve layers from DI, register `IOverlayLayer` or `IOverlayLayerFactory` implementations and set the registry provider:

```csharp
OverlayLayerRegistry.UseServiceProvider(serviceProvider);
```

Set `OverlayHost.UseServiceLayers="True"` (default) to include DI-provided layers alongside the local `OverlayLayers` collection.

## Visual tree lifecycle
Use `VisualTreeLifecycleBehavior.IsEnabled="True"` on the root `OverlayHost` so overlays rebind when windows or dock controls move in the visual tree.

```xml
<OverlayHost VisualTreeLifecycleBehavior.IsEnabled="True">
<DockControl Layout="{Binding}" />
</OverlayHost>
```
Loading