public static bool Merge(ToolStrip sourceToolStrip, ToolStrip targetToolStrip) { // Check for exceptions if (sourceToolStrip == null) { throw new ArgumentNullException("sourceToolStrip"); } if (targetToolStrip == null) { throw new ArgumentNullException("targetName"); } if (targetToolStrip == sourceToolStrip) { throw new ArgumentException("Source and target ToolStrip must be different."); } // If the toolstrips don't allow merging, don't merge them if (!sourceToolStrip.AllowMerge || !targetToolStrip.AllowMerge) { return(false); } // We currently can't support merging multiple times if (sourceToolStrip.IsCurrentlyMerged || targetToolStrip.IsCurrentlyMerged) { return(false); } // What I wouldn't give to be able to modify a collection // while enumerating through it... List <ToolStripItem> items_to_move = new List <ToolStripItem> (); // Create a list of every ToolStripItem we plan on moving foreach (ToolStripItem tsi in sourceToolStrip.Items) { switch (tsi.MergeAction) { case MergeAction.Append: default: items_to_move.Add(tsi); break; case MergeAction.Insert: if (tsi.MergeIndex >= 0) { items_to_move.Add(tsi); } break; case MergeAction.Replace: case MergeAction.Remove: case MergeAction.MatchOnly: foreach (ToolStripItem target_tsi in targetToolStrip.Items) { if (tsi.Text == target_tsi.Text) { items_to_move.Add(tsi); break; } } break; } } // If there was nothing valid to merge, return false if (items_to_move.Count == 0) { return(false); } // Set some state so we can unmerge later sourceToolStrip.BeginMerge(); targetToolStrip.BeginMerge(); sourceToolStrip.SuspendLayout(); targetToolStrip.SuspendLayout(); while (items_to_move.Count > 0) { ToolStripItem tsi = items_to_move[0]; items_to_move.Remove(tsi); switch (tsi.MergeAction) { case MergeAction.Append: default: // Just changing the parent will append it to the target // and remove it from the source ToolStrip.SetItemParent(tsi, targetToolStrip); break; case MergeAction.Insert: // Do the same work as Append, except Insert it into the // location specified by the MergeIndex RemoveItemFromParentToolStrip(tsi); if (tsi.MergeIndex == -1) { continue; } else if (tsi.MergeIndex >= CountRealToolStripItems(targetToolStrip)) { targetToolStrip.Items.AddNoOwnerOrLayout(tsi); } else { targetToolStrip.Items.InsertNoOwnerOrLayout(AdjustItemMergeIndex(targetToolStrip, tsi), tsi); } tsi.Parent = targetToolStrip; break; case MergeAction.Replace: // Find a target ToolStripItem with the same Text, remove it // and replace it with the source one foreach (ToolStripItem target_tsi in targetToolStrip.Items) { if (tsi.Text == target_tsi.Text) { RemoveItemFromParentToolStrip(tsi); // Insert where the old one is, then remove the old one targetToolStrip.Items.InsertNoOwnerOrLayout(targetToolStrip.Items.IndexOf(target_tsi), tsi); targetToolStrip.Items.RemoveNoOwnerOrLayout(target_tsi); // Store the replaced one so we can get it back in unmerge targetToolStrip.HiddenMergedItems.Add(target_tsi); break; } } break; case MergeAction.Remove: // Find a target ToolStripItem with the same Text, and remove // it from the target, nothing else foreach (ToolStripItem target_tsi in targetToolStrip.Items) { if (tsi.Text == target_tsi.Text) { targetToolStrip.Items.RemoveNoOwnerOrLayout(target_tsi); // Store the removed one so we can get it back in unmerge targetToolStrip.HiddenMergedItems.Add(target_tsi); break; } } break; case MergeAction.MatchOnly: // Ugh, find the target ToolStripItem with the same Text, and take // all the subitems from the source one, and append it to the target one foreach (ToolStripItem target_tsi in targetToolStrip.Items) { if (tsi.Text == target_tsi.Text) { if (target_tsi is ToolStripMenuItem && tsi is ToolStripMenuItem) { ToolStripMenuItem source = (ToolStripMenuItem)tsi; ToolStripMenuItem target = (ToolStripMenuItem)target_tsi; ToolStripManager.Merge(source.DropDown, target.DropDown); } break; } } break; } } sourceToolStrip.ResumeLayout(); targetToolStrip.ResumeLayout(); // Store who we merged with, so we can unmerge when only given the target toolstrip sourceToolStrip.CurrentlyMergedWith = targetToolStrip; targetToolStrip.CurrentlyMergedWith = sourceToolStrip; return(true); }