views:

286

answers:

2

I went about creating a custom TabControl widget so that I could accurately paint the tab with a close X on the right edge of the tab. I have a custom array class that holds all of the tabs.

So I override the CreateControlsInstance instance class and redefine the Controls class so I can hide it during reflection serialization.

protected override Control.ControlCollection CreateControlsInstance() {
  return new ControlCollection( this );
}

[Browsable( false ), DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
private new Control.ControlCollection Controls {
  get { return base.Controls; }
}

I then create the override class.

public new class ControlCollection: Control.ControlCollection {
  private xTabControl owner;

  public ControlCollection( xTabControl owner ): base( owner ) {
    this.owner = owner;
  }

  public override void Add( Control value ) {
    if ( !(value is xTabPage) )
      throw new Exception( "The control must be of type xTabPage" );

    xTabPage tabPage = (xTabPage)value;

    if ( !owner.inTabEvent )
      owner._tabPages.Add( tabPage );

    base.Add( value );
  }

  public override void Remove( Control value ) {
    if ( !(value is xTabPage) )
      throw new Exception( "The control must be of type JDMX.Widget.xTabPage" );

    if ( !owner.inTabEvent ) {
      xTabPage tabPage = (xTabPage)value;
      owner._tabPages.Remove( tabPage );
    }

    base.Remove( value );
  }

  public override void Clear() {
    owner._tabPages.Clear();
  }
}

Currently this works but if the Controls class can still call methods SetChildIndex, etc which changes the underlying arraylist but not the tabPages array.

I would like to be able to eliminate the need for the new ControlCollection class to have to use the base class for registering the new xTabPage objects with the xTabControl.

I have already been through the class structure with .Net Reflector. I am hoping to not have to copy half of the Control class in order to get the registration of the new widget to work.

I know this is a long shot but has anyone had any success doing this?

A: 

Well you could use something like .net Reflector (decomplier) to extract the tabcontrol class from .net and edit that class.

Tommy
I have been through the tabcontrol, tabpage, and control classes with .net Reflector. I reason I have to build a custom tab control class is because the existing tabcontrol still would not paint the tab correctly with the additional space needed for the close X. Unlike the combo or list box, there is no OnDrawItem to override to customize the true width of the tab.
JDMX
@jdmx: but there is a property "DrawMode" which you can set it to "OwnerDrawFixed" and handle "DrawItem" event to do your custom painting. Of course there is an OnDrawItem that you can override.
Sameh Serag
I have already spent the time to create a new TabControl which has more features than the Windows TabControl. What I am looking for now is a way to completely eliminate the need to use Control.ControlCollection to register the tabpage panels to the tabcontrol and instead use the TabControl.ControlCollection I have created.
JDMX
A: 

Throughout my research on this, I could not find an instance where UserControls could be managed without using System.Windows.Forms.Control.ControlCollection because of the number of functions the assignment of a Control to the Add function provides. It was even worse when I began to incorporate the Designer into the equation. So I have decided to embrace the Controls property using the custom override I gave above. I will now need to keep my private level _tabPages synced with the Control Collection and not the other way around.

JDMX