Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions docfx/articles/dock-dockable-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Dockable items such as documents, tools and docks implement the `IDockable` inte
| `MaxWidth` | Optional maximum width. Overrides the proportion if smaller. |
| `MinHeight` | Optional minimum height. Overrides the current proportion if larger. |
| `MaxHeight` | Optional maximum height. Overrides the proportion if smaller. |
| `DockingState` | Logical docking state (`DockingWindowState` flags) such as `Docked`, `Pinned`, `Document`, optionally combined with `Floating` and `Hidden`. When a parent dock is hidden, descendants also include `Hidden`. |
| `CanClose` | Whether the user can close the dockable via UI commands. |
| `CanPin` | Allows pinning and unpinning of tools. |
| `KeepPinnedDockableVisible` | Keeps pinned previews visible instead of auto-hiding. |
Expand Down Expand Up @@ -65,6 +66,8 @@ In XAML you set them as attributes:
CanFloat="True" />
```

`DockingState` is maintained by factory operations (`PinDockable`, `UnpinDockable`, `FloatDockable`, `HideDockable`, `RestoreDockable`) and can be used by UI bindings for diagnostics or state-aware visuals.

Global drag and drop behavior can be toggled using the attached properties from [`Dock.Settings`](dock-settings.md):

```xaml
Expand Down
14 changes: 14 additions & 0 deletions docfx/articles/dock-enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,20 @@ Indicates the current state of a floating dock window (`IDockWindow.WindowState`
| `Maximized` | Window is maximized. |
| `FullScreen` | Window uses full-screen presentation when supported. |

## DockingWindowState

Represents the logical docking state on `IDockable.DockingState`.
This is a flags enum, so values can be combined (for example `Document | Floating`).

| Value | Description |
| ----- | ----------- |
| `None` | No state assigned. |
| `Docked` | Dockable is hosted in a regular tool/layout dock. |
| `Pinned` | Dockable is pinned in an auto-hide strip. |
| `Document` | Dockable is hosted in a document dock. |
| `Floating` | Dockable belongs to a floating window root. |
| `Hidden` | Dockable is currently in `IRootDock.HiddenDockables`. |

## GripMode

Determines how the grip element in tool chrome behaves (used by tool docks).
Expand Down
12 changes: 11 additions & 1 deletion docfx/articles/dock-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This reference summarizes the most commonly used classes in Dock. It is based on

| Type | Description |
| --- | --- |
| `IDockable` | Base interface for items that can be shown in a dock. Provides `Id`, `Title`, `Context`, optional size limits and lifecycle methods like `OnClose`. |
| `IDockable` | Base interface for items that can be shown in a dock. Provides `Id`, `Title`, `Context`, `DockingState`, optional size limits and lifecycle methods like `OnClose`. |
| `IDock` | Extends `IDockable` with visible dockables (`VisibleDockables`, `ActiveDockable`, `DefaultDockable`, `FocusedDockable`) and navigation commands (`GoBack`, `GoForward`, `Navigate`, `Close`). It also exposes `OpenedDockablesCount`, `IsActive`, `EnableGlobalDocking`, and `CanCloseLastDockable`. |
| `IRootDock` | The top-level container. In addition to the `IDock` members it exposes pinned dock collections and commands to manage windows. |
| `IProportionalDock` | A dock that lays out its children horizontally or vertically using a `Proportion` value. |
Expand Down Expand Up @@ -44,6 +44,16 @@ The adapter starts with `NaN` coordinates until a value is set.
These values are consulted when calculating drop targets or restoring a layout
from a saved state.

## Docking state flags

`IDockable.DockingState` tracks logical placement using `DockingWindowState` flags:

- `Docked`, `Pinned`, or `Document` describe primary location.
- `Floating` is added when the dockable is hosted in a floating window.
- `Hidden` is added when the dockable is moved to `IRootDock.HiddenDockables`.

Common combinations include `Docked | Floating`, `Pinned | Floating`, and `Document | Floating | Hidden`.

## Document dock options

`IDocumentDock` exposes several key properties for controlling its behavior:
Expand Down
4 changes: 3 additions & 1 deletion docfx/articles/dock-restore-dockable.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ IDockable? RestoreDockable(string id);
4. **Fire Restored Event**: Triggers the `DockableRestored` event
5. **Restore to Original Owner**: If the dockable has an `OriginalOwner`, adds it back to that dock's `VisibleDockables`
6. **Update Ownership**: Sets the dockable's `Owner` to the original owner and clears `OriginalOwner`
7. **Fire Added Event**: Triggers the `DockableAdded` event
7. **Update DockingState**: Recomputes `IDockable.DockingState` for the restored dockable and descendants (for example clears `Hidden` and restores `Docked`/`Pinned`/`Document` with optional `Floating`)
8. **Fire Added Event**: Triggers the `DockableAdded` event

### String Overload Behavior

Expand All @@ -53,6 +54,7 @@ if (dockable.OriginalOwner is IDock owner)
OnDockableAdded(dockable);
dockable.Owner = owner;
dockable.OriginalOwner = null;
UpdateDockingWindowStateRecursive(dockable);
}
```

Expand Down
2 changes: 1 addition & 1 deletion docfx/articles/dock-serialization-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This guide explains how to persist and restore dock state using `DockState`. The [DockXamlSample](https://github.com/wieslawsoltes/Dock/tree/master/samples/DockXamlSample) shows these steps in a working application.

`DockState` stores tool and document content (and document templates for document docks) so that those values can be restored after a layout is loaded. Active and focused dockables are part of the layout model and are serialized with the layout itself.
`DockState` stores tool and document content (and document templates for document docks) so that those values can be restored after a layout is loaded. Active/focused dockables and `IDockable.DockingState` are part of the layout model and are serialized with the layout itself.

## Saving the state

Expand Down
2 changes: 1 addition & 1 deletion docfx/articles/dock-serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ DI-based construction, use the `Dock.Serializer.DockSerializer` overload that ac
2. Load the layout and call `_dockState.Restore` to restore content/templates if needed.
3. Handle the case where the layout file does not exist or fails to deserialize.

Following this pattern keeps the window arrangement consistent across sessions. Floating window bounds, title, and `WindowState` are serialized as part of `IDockWindow`.
Following this pattern keeps the window arrangement consistent across sessions. Floating window bounds, title, and `WindowState` are serialized as part of `IDockWindow`. Dockables also persist `DockingState` (`DockingWindowState` flags), so state-aware UI can restore pinned/document/floating/hidden metadata consistently.

## Dockable identifiers

Expand Down
2 changes: 1 addition & 1 deletion docfx/articles/dock-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This document explains why `DockState` exists and how to use it when saving and

`DockState` captures values that are not serialized with the layout itself, such as `IToolContent.Content`, `IDocumentContent.Content`, and `IDocumentDockContent.DocumentTemplate`. These properties often reference controls or templates that are intentionally ignored by serializers. Without `DockState`, documents or tools can appear with missing content after a layout is loaded.

Active and focused dockables are part of the layout model and are serialized directly, so `DockState` is not required for focus restoration.
Active and focused dockables are part of the layout model and are serialized directly, so `DockState` is not required for focus restoration. Dockable logical placement (`IDockable.DockingState`) is also part of the layout model and is updated by factory operations.

## When to create a DockState

Expand Down
7 changes: 6 additions & 1 deletion samples/DockMvvmSample/Views/DockableOptionsView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xmlns:dm="using:Dock.Model.Core"
xmlns:views="using:DockMvvmSample.Views"
x:DataType="dm:IDockable" x:CompileBindings="True">
<Grid RowDefinitions="Auto,Auto">
<Grid RowDefinitions="Auto,Auto,Auto">
<StackPanel Orientation="Horizontal" Spacing="2">
<CheckBox IsChecked="{Binding CanClose}" ToolTip.Tip="CanClose" />
<CheckBox IsChecked="{Binding CanFloat}" ToolTip.Tip="CanFloat" />
Expand All @@ -25,5 +25,10 @@
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Grid.Row="2"
ItemsSource="{x:Static views:DockableOptionsView.DockingWindowStateOptions}"
SelectedItem="{Binding DockingState}"
ToolTip.Tip="DockingState"
MinWidth="110" />
</Grid>
</UserControl>
15 changes: 15 additions & 0 deletions samples/DockMvvmSample/Views/DockableOptionsView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ public partial class DockableOptionsView : UserControl
PinnedDockDisplayMode.Inline
};

public static DockingWindowState[] DockingWindowStateOptions { get; } =
{
DockingWindowState.Docked,
DockingWindowState.Pinned,
DockingWindowState.Document,
DockingWindowState.Docked | DockingWindowState.Floating,
DockingWindowState.Pinned | DockingWindowState.Floating,
DockingWindowState.Document | DockingWindowState.Floating,
DockingWindowState.Docked | DockingWindowState.Hidden,
DockingWindowState.Pinned | DockingWindowState.Hidden,
DockingWindowState.Document | DockingWindowState.Hidden,
DockingWindowState.Docked | DockingWindowState.Floating | DockingWindowState.Hidden,
DockingWindowState.Document | DockingWindowState.Floating | DockingWindowState.Hidden
};

public DockableOptionsView()
{
InitializeComponent();
Expand Down
7 changes: 6 additions & 1 deletion samples/DockReactiveUISample/Views/DockableOptionsView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xmlns:dm="using:Dock.Model.Core"
xmlns:views="using:DockReactiveUISample.Views"
x:DataType="dm:IDockable" x:CompileBindings="True">
<Grid RowDefinitions="Auto,Auto">
<Grid RowDefinitions="Auto,Auto,Auto">
<StackPanel Orientation="Horizontal" Spacing="2">
<CheckBox IsChecked="{Binding CanClose}" ToolTip.Tip="CanClose" />
<CheckBox IsChecked="{Binding CanFloat}" ToolTip.Tip="CanFloat" />
Expand All @@ -25,5 +25,10 @@
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Grid.Row="2"
ItemsSource="{x:Static views:DockableOptionsView.DockingWindowStateOptions}"
SelectedItem="{Binding DockingState}"
ToolTip.Tip="DockingState"
MinWidth="110" />
</Grid>
</UserControl>
15 changes: 15 additions & 0 deletions samples/DockReactiveUISample/Views/DockableOptionsView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ public partial class DockableOptionsView : UserControl
PinnedDockDisplayMode.Inline
};

public static DockingWindowState[] DockingWindowStateOptions { get; } =
{
DockingWindowState.Docked,
DockingWindowState.Pinned,
DockingWindowState.Document,
DockingWindowState.Docked | DockingWindowState.Floating,
DockingWindowState.Pinned | DockingWindowState.Floating,
DockingWindowState.Document | DockingWindowState.Floating,
DockingWindowState.Docked | DockingWindowState.Hidden,
DockingWindowState.Pinned | DockingWindowState.Hidden,
DockingWindowState.Document | DockingWindowState.Hidden,
DockingWindowState.Docked | DockingWindowState.Floating | DockingWindowState.Hidden,
DockingWindowState.Document | DockingWindowState.Floating | DockingWindowState.Hidden
};

public DockableOptionsView()
{
InitializeComponent();
Expand Down
8 changes: 8 additions & 0 deletions src/Dock.Avalonia/Controls/ManagedDockableBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public abstract class ManagedDockableBase : IDockable, IDockSelectorInfo, IDocka
private bool _isCollapsable = true;
private double _proportion = double.NaN;
private DockMode _dock = DockMode.Center;
private DockingWindowState _dockingState = DockingWindowState.Docked;
private int _column;
private int _row;
private int _columnSpan = 1;
Expand Down Expand Up @@ -124,6 +125,13 @@ public DockMode Dock
set => SetProperty(ref _dock, value);
}

/// <inheritdoc />
public DockingWindowState DockingState
{
get => _dockingState;
set => SetProperty(ref _dockingState, value);
}

/// <inheritdoc />
public int Column
{
Expand Down
16 changes: 16 additions & 0 deletions src/Dock.Model.Avalonia/Core/DockableBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ public abstract class DockableBase : ReactiveBase, IDockable, IDockSelectorInfo,
public static readonly DirectProperty<DockableBase, DockMode> DockProperty =
AvaloniaProperty.RegisterDirect<DockableBase, DockMode>(nameof(Dock), o => o.Dock, (o, v) => o.Dock = v);

/// <summary>
/// Defines the <see cref="DockingState"/> property.
/// </summary>
public static readonly DirectProperty<DockableBase, DockingWindowState> DockingStateProperty =
AvaloniaProperty.RegisterDirect<DockableBase, DockingWindowState>(nameof(DockingState), o => o.DockingState, (o, v) => o.DockingState = v, DockingWindowState.Docked);

/// <summary>
/// Defines the <see cref="Column"/> property.
/// </summary>
Expand Down Expand Up @@ -242,6 +248,7 @@ public abstract class DockableBase : ReactiveBase, IDockable, IDockSelectorInfo,
private bool _isCollapsable = true;
private double _proportion = double.NaN;
private DockMode _dock = DockMode.Center;
private DockingWindowState _dockingState = DockingWindowState.Docked;
private int _column = 0;
private int _row = 0;
private int _columnSpan = 1;
Expand Down Expand Up @@ -367,6 +374,15 @@ public DockMode Dock
set => SetAndRaise(DockProperty, ref _dock, value);
}

/// <inheritdoc/>
[DataMember(IsRequired = false, EmitDefaultValue = true)]
[JsonPropertyName("DockingState")]
public DockingWindowState DockingState
{
get => _dockingState;
set => SetAndRaise(DockingStateProperty, ref _dockingState, value);
}

/// <inheritdoc/>
[DataMember(IsRequired = false, EmitDefaultValue = true)]
[JsonPropertyName("Column")]
Expand Down
Loading
Loading