/// <summary> /// When redirecting the add operation, find the parent to add the new control to. /// </summary> /// <param name="adapterService">Adapter service.</param> /// <param name="parent">The parent item.</param> /// <param name="childType">The type of child item.</param> /// <param name="index">Index of the last child of the parent.</param> /// <returns>The parent to add the new control to.</returns> private static ModelItem FindSuitableParent(AdapterService adapterService, ModelItem parent, Type childType, int index) { ModelItem suitableParent = null; if (adapterService != null) { ParentAdapter parentAdapter = adapterService.GetAdapter <ParentAdapter>(parent.Content.Collection[index].ItemType); Debug.Assert(parentAdapter != null, "Parent Adapter cannot be null"); List <ModelItem> parentList = new List <ModelItem>(); ModelItem targetParent = parent.Content.Collection[index]; ModelItem redirectedParent = parentAdapter.RedirectParent(parent.Content.Collection[index], childType); parentList.Add(targetParent); parentList.Add(redirectedParent); while (redirectedParent != targetParent) { targetParent = redirectedParent; parentAdapter = adapterService.GetAdapter <ParentAdapter>(targetParent.ItemType); Debug.Assert(parentAdapter != null, "Parent Adapter for Redirected Parent cannot be null"); redirectedParent = parentAdapter.RedirectParent(targetParent, childType); if (parentList.Contains(redirectedParent)) { break; // To avoid recursion } else { parentList.Add(redirectedParent); } } if (parentAdapter.CanParent(targetParent, childType)) { suitableParent = targetParent; } } return(suitableParent); }
/// <summary> /// When redirecting the add operation, find the parent to add the new control to. /// </summary> /// <param name="adapterService">Adapter service.</param> /// <param name="parent">The parent item.</param> /// <param name="childType">The type of child item.</param> /// <param name="index">Index of the last child of the parent.</param> /// <returns>The parent to add the new control to.</returns> private static ModelItem FindSuitableParent(AdapterService adapterService, ModelItem parent, Type childType, int index) { ModelItem suitableParent = null; if (adapterService != null) { ParentAdapter parentAdapter = adapterService.GetAdapter<ParentAdapter>(parent.Content.Collection[index].ItemType); Debug.Assert(parentAdapter != null, "Parent Adapter cannot be null"); List<ModelItem> parentList = new List<ModelItem>(); ModelItem targetParent = parent.Content.Collection[index]; ModelItem redirectedParent = parentAdapter.RedirectParent(parent.Content.Collection[index], childType); parentList.Add(targetParent); parentList.Add(redirectedParent); while (redirectedParent != targetParent) { targetParent = redirectedParent; parentAdapter = adapterService.GetAdapter<ParentAdapter>(targetParent.ItemType); Debug.Assert(parentAdapter != null, "Parent Adapter for Redirected Parent cannot be null"); redirectedParent = parentAdapter.RedirectParent(targetParent, childType); if (parentList.Contains(redirectedParent)) { break; // To avoid recursion } else { parentList.Add(redirectedParent); } } if (parentAdapter.CanParent(targetParent, childType)) { suitableParent = targetParent; } } return suitableParent; }
/// <summary> /// Parent the given control into the TabControl. /// </summary> /// <param name="parent">The new parent item for child.</param> /// <param name="child">The child item.</param> public override void Parent(ModelItem parent, ModelItem child) { if (parent == null) { throw new ArgumentNullException("parent"); } if (child == null) { throw new ArgumentNullException("child"); } // Clear existing property values that we don't want to apply to the new container. child.Properties[MyPlatformTypes.FrameworkElement.MarginProperty].ClearValue(); child.Properties[MyPlatformTypes.FrameworkElement.HorizontalAlignmentProperty].ClearValue(); child.Properties[MyPlatformTypes.FrameworkElement.VerticalAlignmentProperty].ClearValue(); bool childIsTabItem = child.IsItemOfType(MyPlatformTypes.TabItem.TypeId); // We always accept parenting in TabControl if there is not active focused Task. // If the control being pasted is not TabItem and TabControl is empty (doesnt have any TabItem(s) in it) // then we inject a TabItem with Grid in TabControl and paste the control under consideration in TabItem. // We inject a TabItem also in cases when active TabItem is not capable of parenting concerned control if (!childIsTabItem) { // Based on evaluation done in RedirectParent(), // if any control other than TabItem is being parented to Control in this Parent() call // then we need to add a new Tabitem with Grid in it try { ModelItem newTabItem = ModelFactory.CreateItem(parent.Context, MyPlatformTypes.TabItem.TypeId, CreateOptions.InitializeDefaults); parent.Content.Collection.Add(newTabItem); // activate the newly added tabItem TabItemDesignModeValueProvider.SetDesignTimeIsSelected(newTabItem, true); int index = parent.Content.Collection.Count - 1; // Find a suitable parent for control to be pasted. // Since we always accept parenting for TabControl when there is no active focused task, // we better make sure this works. AdapterService adapterService = parent.Context.Services.GetService <AdapterService>(); if (adapterService != null) { ModelItem targetParent = FindSuitableParent(adapterService, parent, child.ItemType, index); if (targetParent != null) { ParentAdapter parentAdapter = adapterService.GetAdapter <ParentAdapter>(targetParent.ItemType); parentAdapter.Parent(targetParent, child); } else { Debug.Assert(targetParent != null, "Parenting failed!"); } } } catch (Exception ex) { throw new InvalidOperationException("Parenting Failed", ex.InnerException); } } else { // child being added is a TabItem; child.Properties[MyPlatformTypes.TabItem.IsSelectedProperty].ClearValue(); parent.Content.Collection.Add(child); TabItemDesignModeValueProvider.SetDesignTimeIsSelected(child, true); // Activate the newly added tabItem } }