I understand how it works now... After using ILspy to decompile the source for TabControlDesigner and TabControl itself, I can see that I need to re-design my collection of Panels. Instead of using a simple ArrayList collection, I need to build a collection myself and overload the .Add() methods so that it will simultaneously add the LVPanel to its own collection, and to the Control.Controls collection. Took a lot of looking around, but I get it now.
public class TabControl : Control
{
public class TabPageCollection : IList, ICollection, IEnumerable
{
private TabControlNew owner;
private int lastAccessedIndex = -1;
public virtual TabPage this[int index]
{
get
{
return this.owner.GetTabPage(index);
}
set
{
this.owner.SetTabPage(index, value, value.GetTCITEM());
}
}
object IList.this[int index]
{
get
{
return this[index];
}
set
{
if (value is TabPage)
{
this[index] = (TabPage)value;
return;
}
throw new ArgumentException("value");
}
}
public virtual TabPage this[string key]
{
get
{
if (string.IsNullOrEmpty(key))
{
return null;
}
int index = this.IndexOfKey(key);
if (this.IsValidIndex(index))
{
return this[index];
}
return null;
}
}
[Browsable(false)]
public int Count
{
get
{
return this.owner.tabPageCount;
}
}
object ICollection.SyncRoot
{
get
{
return this;
}
}
bool ICollection.IsSynchronized
{
get
{
return false;
}
}
bool IList.IsFixedSize
{
get
{
return false;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public TabPageCollection(TabControlNew owner)
{
if (owner == null)
{
throw new ArgumentNullException("owner");
}
this.owner = owner;
}
public void Add(TabPage value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
this.owner.Controls.Add(value);
}
int IList.Add(object value)
{
if (value is TabPage)
{
this.Add((TabPage)value);
return this.IndexOf((TabPage)value);
}
throw new ArgumentException("value");
}
public void Add(string text)
{
this.Add(new TabPage
{
Text = text
});
}
public void Add(string key, string text)
{
this.Add(new TabPage
{
Name = key,
Text = text
});
}
public void Add(string key, string text, int imageIndex)
{
this.Add(new TabPage
{
Name = key,
Text = text,
ImageIndex = imageIndex
});
}
public void Add(string key, string text, string imageKey)
{
this.Add(new TabPage
{
Name = key,
Text = text,
ImageKey = imageKey
});
}
public void AddRange(TabPage[] pages)
{
if (pages == null)
{
throw new ArgumentNullException("pages");
}
for (int i = 0; i < pages.Length; i++)
{
TabPage value = pages[i];
this.Add(value);
}
}
public bool Contains(TabPage page)
{
if (page == null)
{
throw new ArgumentNullException("value");
}
return this.IndexOf(page) != -1;
}
bool IList.Contains(object page)
{
return page is TabPage && this.Contains((TabPage)page);
}
public virtual bool ContainsKey(string key)
{
return this.IsValidIndex(this.IndexOfKey(key));
}
public int IndexOf(TabPage page)
{
if (page == null)
{
throw new ArgumentNullException("value");
}
for (int i = 0; i < this.Count; i++)
{
if (this[i] == page)
{
return i;
}
}
return -1;
}
int IList.IndexOf(object page)
{
if (page is TabPage)
{
return this.IndexOf((TabPage)page);
}
return -1;
}
public virtual int IndexOfKey(string key)
{
if (string.IsNullOrEmpty(key))
{
return -1;
}
if (this.IsValidIndex(this.lastAccessedIndex) && WindowsFormsUtils.SafeCompareStrings(this[this.lastAccessedIndex].Name, key, true))
{
return this.lastAccessedIndex;
}
for (int i = 0; i < this.Count; i++)
{
if (WindowsFormsUtils.SafeCompareStrings(this[i].Name, key, true))
{
this.lastAccessedIndex = i;
return i;
}
}
this.lastAccessedIndex = -1;
return -1;
}
public void Insert(int index, TabPage tabPage)
{
this.owner.InsertItem(index, tabPage);
try
{
this.owner.InsertingItem = true;
this.owner.Controls.Add(tabPage);
}
finally
{
this.owner.InsertingItem = false;
}
this.owner.Controls.SetChildIndex(tabPage, index);
}
void IList.Insert(int index, object tabPage)
{
if (tabPage is TabPage)
{
this.Insert(index, (TabPage)tabPage);
return;
}
throw new ArgumentException("tabPage");
}
public void Insert(int index, string text)
{
this.Insert(index, new TabPage
{
Text = text
});
}
public void Insert(int index, string key, string text)
{
this.Insert(index, new TabPage
{
Name = key,
Text = text
});
}
public void Insert(int index, string key, string text, int imageIndex)
{
TabPage tabPage = new TabPage();
tabPage.Name = key;
tabPage.Text = text;
this.Insert(index, tabPage);
tabPage.ImageIndex = imageIndex;
}
public void Insert(int index, string key, string text, string imageKey)
{
TabPage tabPage = new TabPage();
tabPage.Name = key;
tabPage.Text = text;
this.Insert(index, tabPage);
tabPage.ImageKey = imageKey;
}
private bool IsValidIndex(int index)
{
return index >= 0 && index < this.Count;
}
public virtual void Clear()
{
this.owner.RemoveAll();
}
void ICollection.CopyTo(Array dest, int index)
{
if (this.Count > 0)
{
Array.Copy(this.owner.GetTabPages(), 0, dest, index, this.Count);
}
}
public IEnumerator GetEnumerator()
{
TabPage[] tabPages = this.owner.GetTabPages();
if (tabPages != null)
{
return tabPages.GetEnumerator();
}
return new TabPage[0].GetEnumerator();
}
public void Remove(TabPage value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
this.owner.Controls.Remove(value);
}
void IList.Remove(object value)
{
if (value is TabPage)
{
this.Remove((TabPage)value);
}
}
public void RemoveAt(int index)
{
this.owner.Controls.RemoveAt(index);
}
public virtual void RemoveByKey(string key)
{
int index = this.IndexOfKey(key);
if (this.IsValidIndex(index))
{
this.RemoveAt(index);
}
}
}
public new class ControlCollection : Control.ControlCollection
{
private TabControlNew owner;
public ControlCollection(TabControlNew owner)
: base(owner)
{
this.owner = owner;
}
public override void Add(Control value)
{
if (!(value is TabPage))
{
throw new ArgumentException(SR.GetString("TabControlInvalidTabPageType", new object[]
{
value.GetType().Name
}));
}
TabPage tabPage = (TabPage)value;
if (!this.owner.InsertingItem)
{
if (this.owner.IsHandleCreated)
{
this.owner.AddTabPage(tabPage, tabPage.GetTCITEM());
}
else
{
this.owner.Insert(this.owner.TabCount, tabPage);
}
}
base.Add(tabPage);
tabPage.Visible = false;
if (this.owner.IsHandleCreated)
{
tabPage.Bounds = this.owner.DisplayRectangle;
}
ISite site = this.owner.Site;
if (site != null && tabPage.Site == null)
{
IContainer container = site.Container;
if (container != null)
{
container.Add(tabPage);
}
}
this.owner.ApplyItemSize();
this.owner.UpdateTabSelection(false);
}
public override void Remove(Control value)
{
base.Remove(value);
if (!(value is TabPage))
{
return;
}
int num = this.owner.FindTabPage((TabPage)value);
int selectedIndex = this.owner.SelectedIndex;
if (num != -1)
{
this.owner.RemoveTabPage(num);
if (num == selectedIndex)
{
this.owner.SelectedIndex = 0;
}
}
this.owner.UpdateTabSelection(false);
}
}
private TabControl.TabPageCollection tabCollection;
public TabControl.TabPageCollection TabPages
{
get
{
return this.tabCollection;
}
}