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);
}