/// <summary> /// Successively copy the properties from the <paramref name="sourcePanel"/> to the <paramref name="targetPanel"/>, then swap the panels in the parent /// and finally move the children from the <paramref name="sourcePanel"/> to the <paramref name="targetPanel"/>. /// </summary> private void CopySwapExchange([NotNull] PanelViewModel sourcePanel, [NotNull] UIElementDesign targetPanel, [CanBeNull] Func <IEnumerable <UIElementViewModel>, IEnumerable <UIElementViewModel> > childSorter = null) { var targetPanelElement = targetPanel.UIElement as Panel; if (targetPanelElement == null) { throw new ArgumentException(@"The target element must be a Panel", nameof(targetPanel)); } // Clone common properties CopyCommonProperties(Editor.NodeContainer, sourcePanel.AssetSidePanel, targetPanelElement); // Initialize the new hierarchy of elements that starts from the target and contains all the children IEnumerable <UIElementViewModel> children = sourcePanel.Children.ToList(); var hierarchy = UIAssetPropertyGraph.CloneSubHierarchies(Asset.Session.AssetNodeContainer, Asset.Asset, children.Select(c => c.Id.ObjectId), SubHierarchyCloneFlags.None, out _); hierarchy.RootParts.Add(targetPanel.UIElement); hierarchy.Parts.Add(targetPanel); // Remove all children from the source panel. foreach (var child in children) { Asset.AssetHierarchyPropertyGraph.RemovePartFromAsset(child.UIElementDesign); } // Swap panels in the parent var elementParent = Parent as UIElementViewModel; var rootParent = Parent as UIRootViewModel; if (rootParent != null) { // special case of RootElement rootParent.ReplaceRootElement(sourcePanel, hierarchy, targetPanelElement.Id); } else if (elementParent != null) { // Remove current panel from Parent var index = elementParent.Children.IndexOf(sourcePanel); Asset.AssetHierarchyPropertyGraph.RemovePartFromAsset(sourcePanel.UIElementDesign); Asset.AssetHierarchyPropertyGraph.AddPartToAsset(hierarchy.Parts, targetPanel, elementParent.AssetSideUIElement, index); } else { throw new InvalidOperationException(); } // Sort the children list before re-inserting them in the target panel. children = childSorter?.Invoke(children) ?? children; // Then populate the target panel foreach (var child in children) { Asset.InsertUIElement(hierarchy.Parts, hierarchy.Parts[child.Id.ObjectId], targetPanelElement); } }
public abstract void ReplaceRootElement([NotNull] PanelViewModel sourcePanel, [NotNull] AssetCompositeHierarchyData <UIElementDesign, UIElement> hierarchy, Guid targetPanelId);