fix(docking): prevent layout tree loss and enforce cross-layout ownership

This commit is contained in:
2026-03-28 23:07:28 +09:00
parent 0d8bc6f868
commit e9f822409d
2 changed files with 19 additions and 2 deletions

View File

@@ -47,6 +47,9 @@ public abstract class DockContainer : DockModule
{ {
ValidateChild(module); ValidateChild(module);
if (module.Owner == null && module.Root != null && module.Root != this.Root)
throw new InvalidOperationException("Cannot insert a module that is the root of another layout. Detach it first.");
if (index < 0 || index > _children.Count) if (index < 0 || index > _children.Count)
throw new ArgumentOutOfRangeException(nameof(index)); throw new ArgumentOutOfRangeException(nameof(index));
@@ -94,6 +97,9 @@ public abstract class DockContainer : DockModule
ArgumentNullException.ThrowIfNull(oldChild); ArgumentNullException.ThrowIfNull(oldChild);
ValidateChild(newChild); ValidateChild(newChild);
if (newChild.Owner == null && newChild.Root != null && newChild.Root != this.Root)
throw new InvalidOperationException("Cannot insert a module that is the root of another layout. Detach it first.");
if (oldChild == newChild) return; if (oldChild == newChild) return;
int index = _children.IndexOf(oldChild); int index = _children.IndexOf(oldChild);

View File

@@ -104,12 +104,23 @@ public class DockingLayout : Control
{ {
// Root is not a container, or contains no groups. Wrap it. // Root is not a container, or contains no groups. Wrap it.
var newGroup = new DockGroup(); var newGroup = new DockGroup();
newGroup.AddChild(document);
if (RootModule is DockDocument existingDoc) if (RootModule is DockDocument existingDoc)
{ {
RootModule = null; // Detach first RootModule = null;
newGroup.AddChild(existingDoc); newGroup.AddChild(existingDoc);
}
RootModule = newGroup; RootModule = newGroup;
}
else
{
var oldRoot = RootModule;
RootModule = null;
var panel = new DockPanel();
panel.AddChild(oldRoot);
panel.AddChild(newGroup);
RootModule = panel;
}
targetGroup = newGroup; targetGroup = newGroup;
} }
} }