Repository navigation
Description
Issue Description:
When a Document window in AvalonDock is in a floating state, if it is first dragged and docked to a specific location (e.g., docked into a panel or tab group), then converted back to a floating window, subsequent attempts to re-dock it using the "Dock as Tabbed Document" feature will fail. The operation does not complete successfully, and the window remains floating.
Steps to Reproduce:
1.Start with a Document window in its initial docked state (as a tabbed document)
2.Convert the Document window to a floating window (e.g., by dragging it out or using the context menu)
3.Drag the floating window and dock it to a specific location
4.Convert the same window back to a floating state again
5.Attempt to re-dock the window using the "Dock as Tabbed Document" command (via context menu or drag-and-drop)
6.Observe that the docking operation fails – the window does not dock as expected and remains floating
Expected Behavior:
After the window is re-floated, the "Dock as Tabbed Document" command should successfully dock the window back into the document pane, just like the initial docking operation
Actual Behavior:
The docking operation fails; the window remains floating and does not reattach to the document pane.

What I've Found So Far (please correct me if I'm wrong):
After comparing recent behavior changes, I suspect this issue might have started occurring after Pull Request #451. I tried to debug a bit and noticed the following:
PR #451 removed a certain check. This seems to cause the parent LayoutDocumentGroup to be unintentionally removed during the state transition process.
I also noticed that during drag-and-dock operations, the system always creates a new LayoutDocumentGroup to host the LayoutDocument.
After the check was removed in #451, the original parent LayoutDocumentGroup appears to be lost during the float → dock → float sequence. As a result, when we later attempt "Dock as Tabbed Document", there is no valid container to receive the document, causing the operation to fail.
My (very tentative) guess:
Before #451, some validation logic prevented the parent LayoutDocumentGroup from being incorrectly removed.
After #451 removed that check, the parent group gets lost during the float → dock → float → re-dock flow, making the second docking attempt fail.
Possible Fix Directions (just my humble suggestions for consideration):
Improve the LayoutDocumentGroup creation strategy
Currently, a new LayoutDocumentGroup is always created during drag-and-dock. Could we instead reuse or properly preserve the existing parent group when appropriate, rather than creating a new one? This might better support multiple state transitions.
`protected override void Drop(LayoutDocumentFloatingWindow floatingWindow)
{
var targetModel = (ILayoutDocumentPane)_targetPane.Model;
var documentActive = floatingWindow.Descendents().OfType().FirstOrDefault();
var paneGroup = targetModel.Parent as LayoutDocumentPaneGroup;
var requiredOrientation = Type == DropTargetType.DocumentPaneDockBottom || Type == DropTargetType.DocumentPaneDockTop ?
System.Windows.Controls.Orientation.Vertical : System.Windows.Controls.Orientation.Horizontal;
var allowMixedOrientation = targetModel.Root.Manager.AllowMixedOrientation;
if (paneGroup == null)
{
var targetModelAsPositionableElement = (ILayoutPositionableElement)targetModel;
var layoutGroup = (ILayoutGroup)targetModel.Parent;
paneGroup = new LayoutDocumentPaneGroup
{
Orientation = requiredOrientation,
DockWidth = targetModelAsPositionableElement.DockWidth,
DockHeight = targetModelAsPositionableElement.DockHeight,
};
paneGroup.Children.Add(targetModel);
layoutGroup.InsertChildAt(0, paneGroup);
}
else if (allowMixedOrientation && paneGroup.Orientation != requiredOrientation && Type != DropTargetType.DocumentPaneDockInside)
{
var targetModelAsPositionableElement = (ILayoutPositionableElement)targetModel;
var newGroup = new LayoutDocumentPaneGroup
{
Orientation = requiredOrientation,
DockWidth = targetModelAsPositionableElement.DockWidth,
DockHeight = targetModelAsPositionableElement.DockHeight,
};
paneGroup.ReplaceChild(targetModel, newGroup);
newGroup.Children.Add(targetModel);
paneGroup = newGroup;
}
.......................................................................................
}`
Closing Note:
Thank you very much for taking the time to read this. I'm just a regular user who noticed some strange behavior and tried to dig a little deeper. My understanding could be completely off — please feel free to correct me. I would greatly appreciate any advice or pointers.
I'm happy to help test any potential fixes if that would be useful.
Activity
sharpSteff commentedon Apr 24, 2026
@john-lemon7 Thanks for creating/finding this issue. I created a PR for this. Can you verify that this fixes your issue?
sharpSteff commentedon Apr 24, 2026
In the testApp I can not reproduce that issue any more.
john-lemon7 commentedon Apr 25, 2026
@sharpSteff Thanks for your follow-up. I’ve verified the PR, and it does fix the issue on my end. Really appreciate your work on this.
sharpSteff commentedon Apr 25, 2026
@john-lemon7 Thanks for verifying. I probably release a minor release on sunday
Fix #551 (#552)
Fix floating window drop reentrancy, migrate tests to NUnit, add upst…
Cherry-pick upstream bug fixes: CloseInternal null safety, DockAsDocu…