By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,836 Members | 2,028 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,836 IT Pros & Developers. It's quick & easy.

Adding custom TabPages at design time

P: n/a
Hi All, does anyone know how to add TabPages of ones own classes at design time ? ideally when adding a new TabControl it would
contain tab pages of my own classes, I know you can achieve this with ListView columns so it should be doable, thanks
Dec 13 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Either add the ToolBoxItemAttribute to your custom TabPage Class so that you
can drag and drop it from the toolbox, or Inherit from TabControl and give
it a custom TabPageCollection.

You'll find an example of the latter on my TabControls tips page
http://www.dotnetrix.co.uk/tabcontrols.html

For VS2005 you'll need to add a ScrollableControlDesigner to the custom
TabPage or it will misbehave in the IDE.

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html
"Pete Kane" <pj**********@uku.co.ukwrote in message
news:eG*************@TK2MSFTNGP02.phx.gbl...
Hi All, does anyone know how to add TabPages of ones own classes at design
time ? ideally when adding a new TabControl it would contain tab pages of
my own classes, I know you can achieve this with ListView columns so it
should be doable, thanks

Dec 13 '06 #2

P: n/a
Mick Doherty wrote:
Either add the ToolBoxItemAttribute to your custom TabPage Class so that you
can drag and drop it from the toolbox, or Inherit from TabControl and give
it a custom TabPageCollection.

You'll find an example of the latter on my TabControls tips page
http://www.dotnetrix.co.uk/tabcontrols.html

For VS2005 you'll need to add a ScrollableControlDesigner to the custom
TabPage or it will misbehave in the IDE.
Thanks Mick, It (your sample tabcontrol with custom tabpages) looks very impressive but which parts do I need to have my custom
pages added by default (i.e. when adding a tabcontrol in the IDE) and when adding subsequent pages in the designer ? thanks a lot
Dec 14 '06 #3

P: n/a
You need most of the code.

The actual TabControl and Custom TabPage class are not too extensive. In
order to modify the DesignerVerbs (Add Tab, Remove Tab) you must supply a
custom TabControlDesigner, and in VS2005 you must supply a custom
TabPageDesigner.

The TabPageDesigner is very simple as it only needs to be assigned as a
ScrollableControlDesigner, but the TabControlDesigner is quite complex as
the control needs to be navigated at DesignTime as well as at Runtime and
the System.Windows.Forms.Design.TabControlDesigner cannot be Inherited.

I've created an example in it's most basic form, but there's still a fair
amount of code here.

The System.Windows.Forms.TabPage will misbehave in the VS2005 IDE, and so I
have created a basic TabPage class with no special function. It is simply an
Inherited System.Windows.Forms.TabPage which uses a ScrollControlDesigner.
All of your Custom TabPages should be inherited from this class. For the
purpose of the example, I have created a RandomColorTabPage, just to show
implementation.

The Add verb/SmartTag will add a basic TabPage.
The CollectionEditor will add a basic TabPage if you simply click on the Add
button, but the button has a dropdown which will allow you to choose a
RandomColorTabPage to add instead.
To change the TabPage types that will show in the dropdown list, simply
modify the MyTabPageCollectionEditor's CreateNewItemTypes() method to return
the Type Array that you want.
To Change the TabPage type added via the Add Tab verb, simply modify the
type in the TabControlDesigner's OnAddPage() method.
At runtime you may add instances of System.Windows.Forms.TabPage without
penalty.

Here's the code: (note that you will need to add a reference to
System.Design.dll)
\\\
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;

namespace Dotnetrix.Examples
{
[Designer(typeof(MyTabControlDesigner))]
public class MyTabControl : System.Windows.Forms.TabControl
{
[Editor(typeof(MyTabPageCollectionEditor), typeof(UITypeEditor))]
public new TabPageCollection TabPages
{
get
{
return base.TabPages;
}
}

internal class MyTabPageCollectionEditor : CollectionEditor
{
protected override CollectionEditor.CollectionForm
CreateCollectionForm()
{
CollectionForm baseForm = base.CreateCollectionForm();
baseForm.Text = "MyTabPage Collection Editor";
return baseForm;
}

public MyTabPageCollectionEditor(System.Type type)
: base(type)
{
}
protected override Type CreateCollectionItemType()
{
return typeof(RandomColorTabPage);
}
protected override Type[] CreateNewItemTypes()
{
return new Type[] { typeof(TabPage),
typeof(RandomColorTabPage) };
}

}

}

[Designer(typeof(System.Windows.Forms.Design.Scroll ableControlDesigner))]
public class TabPage : System.Windows.Forms.TabPage
{
public TabPage()
: base()
{
}
}

public class RandomColorTabPage : TabPage
{
public RandomColorTabPage()
: base()
{
this.BackColor = RandomColor();
}

private static Random ColorRandomizer = new Random();

private System.Drawing.Color RandomColor()
{
return System.Drawing.Color.FromArgb(ColorRandomizer.Next (256),
ColorRandomizer.Next(256),
ColorRandomizer.Next(256));
}
}
internal class MyTabControlDesigner :
System.Windows.Forms.Design.ParentControlDesigner
{

#region Private Instance Variables

private DesignerVerbCollection m_verbs = new
DesignerVerbCollection();
private IDesignerHost m_DesignerHost;
private ISelectionService m_SelectionService;

#endregion

public MyTabControlDesigner()
: base()
{
DesignerVerb verb1 = new DesignerVerb("Add Tab", new
EventHandler(OnAddPage));
DesignerVerb verb2 = new DesignerVerb("Remove Tab", new
EventHandler(OnRemovePage));
m_verbs.AddRange(new DesignerVerb[] { verb1, verb2 });
}

#region Properties

public override DesignerVerbCollection Verbs
{
get
{
if (m_verbs.Count == 2)
{
MyTabControl MyControl = (MyTabControl)Control;
if (MyControl.TabCount 0)
{
m_verbs[1].Enabled = true;
}
else
{
m_verbs[1].Enabled = false;
}
}
return m_verbs;
}
}

public IDesignerHost DesignerHost
{
get
{
if (m_DesignerHost == null)
m_DesignerHost =
(IDesignerHost)(GetService(typeof(IDesignerHost))) ;

return m_DesignerHost;
}
}

public ISelectionService SelectionService
{
get
{
if (m_SelectionService == null)
m_SelectionService =
(ISelectionService)(this.GetService(typeof(ISelect ionService)));
return m_SelectionService;
}
}

#endregion

void OnAddPage(Object sender, EventArgs e)
{
MyTabControl ParentControl = (MyTabControl)Control;
System.Windows.Forms.Control.ControlCollection oldTabs =
ParentControl.Controls;

RaiseComponentChanging(TypeDescriptor.GetPropertie s(ParentControl)["TabPages"]);

System.Windows.Forms.TabPage P =
(System.Windows.Forms.TabPage)(DesignerHost.Create Component(typeof(TabPage)));
P.Text = P.Name;
ParentControl.TabPages.Add(P);

RaiseComponentChanged(TypeDescriptor.GetProperties (ParentControl)["TabPages"],
oldTabs, ParentControl.TabPages);
ParentControl.SelectedTab = P;

SetVerbs();

}

void OnRemovePage(Object sender, EventArgs e)
{
MyTabControl ParentControl = (MyTabControl)Control;
System.Windows.Forms.Control.ControlCollection oldTabs =
ParentControl.Controls;

if (ParentControl.SelectedIndex < 0) return;

RaiseComponentChanging(TypeDescriptor.GetPropertie s(ParentControl)["TabPages"]);

DesignerHost.DestroyComponent(ParentControl.TabPag es[ParentControl.SelectedIndex]);

RaiseComponentChanged(TypeDescriptor.GetProperties (ParentControl)["TabPages"],
oldTabs, ParentControl.TabPages);

SelectionService.SetSelectedComponents(new IComponent[] {
ParentControl }, SelectionTypes.Auto);

SetVerbs();

}

private void SetVerbs()
{
MyTabControl ParentControl = (MyTabControl)Control;

switch (ParentControl.TabPages.Count)
{
case 0:
Verbs[1].Enabled = false;
break;
default:
Verbs[1].Enabled = true;
break;
}
}

private const int WM_NCHITTEST = 0x84;

private const int HTTRANSPARENT = -1;
private const int HTCLIENT = 1;

protected override void WndProc(ref System.Windows.Forms.Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCHITTEST)
{
//select tabcontrol when Tabcontrol clicked outside of
TabItem.
if (m.Result.ToInt32() == HTTRANSPARENT)
m.Result = (IntPtr)HTCLIENT;
}

}

private enum TabControlHitTest
{
TCHT_NOWHERE = 1,
TCHT_ONITEMICON = 2,
TCHT_ONITEMLABEL = 4,
TCHT_ONITEM = TCHT_ONITEMICON | TCHT_ONITEMLABEL
}

private const int TCM_HITTEST = 0x130D;

private struct TCHITTESTINFO
{
public System.Drawing.Point pt;
public TabControlHitTest flags;
}

protected override bool GetHitTest(System.Drawing.Point point)
{
if (this.SelectionService.PrimarySelection == this.Control)
{
TCHITTESTINFO hti = new TCHITTESTINFO();

hti.pt = this.Control.PointToClient(point);
hti.flags = 0;

System.Windows.Forms.Message m = new
System.Windows.Forms.Message();
m.HWnd = this.Control.Handle;
m.Msg = TCM_HITTEST;

IntPtr lparam =
System.Runtime.InteropServices.Marshal.AllocHGloba l(System.Runtime.InteropServices.Marshal.SizeOf(ht i));
System.Runtime.InteropServices.Marshal.StructureTo Ptr(hti,
lparam, false);
m.LParam = lparam;

base.WndProc(ref m);
System.Runtime.InteropServices.Marshal.FreeHGlobal (lparam);

if (m.Result.ToInt32() != -1)
return hti.flags != TabControlHitTest.TCHT_NOWHERE;

}

return false;
}

protected override void
OnPaintAdornments(System.Windows.Forms.PaintEventA rgs pe)
{
//Don't want DrawGrid dots.
}

//Fix the AllSizable selectionrule on DockStyle.Fill
public override System.Windows.Forms.Design.SelectionRules
SelectionRules
{
get
{
if (Control.Dock == System.Windows.Forms.DockStyle.Fill)
return
System.Windows.Forms.Design.SelectionRules.Visible ;
return base.SelectionRules;
}
}

}

}
///

HTH

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html
"Pete Kane" <pj**********@uku.co.ukwrote in message
news:ez**************@TK2MSFTNGP03.phx.gbl...
Mick Doherty wrote:
>Either add the ToolBoxItemAttribute to your custom TabPage Class so that
you can drag and drop it from the toolbox, or Inherit from TabControl and
give it a custom TabPageCollection.

You'll find an example of the latter on my TabControls tips page
http://www.dotnetrix.co.uk/tabcontrols.html

For VS2005 you'll need to add a ScrollableControlDesigner to the custom
TabPage or it will misbehave in the IDE.

Thanks Mick, It (your sample tabcontrol with custom tabpages) looks very
impressive but which parts do I need to have my custom pages added by
default (i.e. when adding a tabcontrol in the IDE) and when adding
subsequent pages in the designer ? thanks a lot

Dec 14 '06 #4

P: n/a
Mick Doherty wrote:
You need most of the code.

The actual TabControl and Custom TabPage class are not too extensive. In
order to modify the DesignerVerbs (Add Tab, Remove Tab) you must supply a
custom TabControlDesigner, and in VS2005 you must supply a custom
TabPageDesigner.

The TabPageDesigner is very simple as it only needs to be assigned as a
ScrollableControlDesigner, but the TabControlDesigner is quite complex as
the control needs to be navigated at DesignTime as well as at Runtime and
the System.Windows.Forms.Design.TabControlDesigner cannot be Inherited.

I've created an example in it's most basic form, but there's still a fair
amount of code here.

The System.Windows.Forms.TabPage will misbehave in the VS2005 IDE, and so I
have created a basic TabPage class with no special function. It is simply an
Inherited System.Windows.Forms.TabPage which uses a ScrollControlDesigner.
All of your Custom TabPages should be inherited from this class. For the
purpose of the example, I have created a RandomColorTabPage, just to show
implementation.

The Add verb/SmartTag will add a basic TabPage.
The CollectionEditor will add a basic TabPage if you simply click on the Add
button, but the button has a dropdown which will allow you to choose a
RandomColorTabPage to add instead.
To change the TabPage types that will show in the dropdown list, simply
modify the MyTabPageCollectionEditor's CreateNewItemTypes() method to return
the Type Array that you want.
To Change the TabPage type added via the Add Tab verb, simply modify the
type in the TabControlDesigner's OnAddPage() method.
At runtime you may add instances of System.Windows.Forms.TabPage without
penalty.

Here's the code: (note that you will need to add a reference to
System.Design.dll)
\\\
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;

namespace Dotnetrix.Examples
{
[Designer(typeof(MyTabControlDesigner))]
public class MyTabControl : System.Windows.Forms.TabControl
{
[Editor(typeof(MyTabPageCollectionEditor), typeof(UITypeEditor))]
public new TabPageCollection TabPages
{
get
{
return base.TabPages;
}
}

internal class MyTabPageCollectionEditor : CollectionEditor
{
protected override CollectionEditor.CollectionForm
CreateCollectionForm()
{
CollectionForm baseForm = base.CreateCollectionForm();
baseForm.Text = "MyTabPage Collection Editor";
return baseForm;
}

public MyTabPageCollectionEditor(System.Type type)
: base(type)
{
}
protected override Type CreateCollectionItemType()
{
return typeof(RandomColorTabPage);
}
protected override Type[] CreateNewItemTypes()
{
return new Type[] { typeof(TabPage),
typeof(RandomColorTabPage) };
}

}

}

[Designer(typeof(System.Windows.Forms.Design.Scroll ableControlDesigner))]
public class TabPage : System.Windows.Forms.TabPage
{
public TabPage()
: base()
{
}
}

public class RandomColorTabPage : TabPage
{
public RandomColorTabPage()
: base()
{
this.BackColor = RandomColor();
}

private static Random ColorRandomizer = new Random();

private System.Drawing.Color RandomColor()
{
return System.Drawing.Color.FromArgb(ColorRandomizer.Next (256),
ColorRandomizer.Next(256),
ColorRandomizer.Next(256));
}
}
internal class MyTabControlDesigner :
System.Windows.Forms.Design.ParentControlDesigner
{

#region Private Instance Variables

private DesignerVerbCollection m_verbs = new
DesignerVerbCollection();
private IDesignerHost m_DesignerHost;
private ISelectionService m_SelectionService;

#endregion

public MyTabControlDesigner()
: base()
{
DesignerVerb verb1 = new DesignerVerb("Add Tab", new
EventHandler(OnAddPage));
DesignerVerb verb2 = new DesignerVerb("Remove Tab", new
EventHandler(OnRemovePage));
m_verbs.AddRange(new DesignerVerb[] { verb1, verb2 });
}

#region Properties

public override DesignerVerbCollection Verbs
{
get
{
if (m_verbs.Count == 2)
{
MyTabControl MyControl = (MyTabControl)Control;
if (MyControl.TabCount 0)
{
m_verbs[1].Enabled = true;
}
else
{
m_verbs[1].Enabled = false;
}
}
return m_verbs;
}
}

public IDesignerHost DesignerHost
{
get
{
if (m_DesignerHost == null)
m_DesignerHost =
(IDesignerHost)(GetService(typeof(IDesignerHost))) ;

return m_DesignerHost;
}
}

public ISelectionService SelectionService
{
get
{
if (m_SelectionService == null)
m_SelectionService =
(ISelectionService)(this.GetService(typeof(ISelect ionService)));
return m_SelectionService;
}
}

#endregion

void OnAddPage(Object sender, EventArgs e)
{
MyTabControl ParentControl = (MyTabControl)Control;
System.Windows.Forms.Control.ControlCollection oldTabs =
ParentControl.Controls;

RaiseComponentChanging(TypeDescriptor.GetPropertie s(ParentControl)["TabPages"]);

System.Windows.Forms.TabPage P =
(System.Windows.Forms.TabPage)(DesignerHost.Create Component(typeof(TabPage)));
P.Text = P.Name;
ParentControl.TabPages.Add(P);

RaiseComponentChanged(TypeDescriptor.GetProperties (ParentControl)["TabPages"],
oldTabs, ParentControl.TabPages);
ParentControl.SelectedTab = P;

SetVerbs();

}

void OnRemovePage(Object sender, EventArgs e)
{
MyTabControl ParentControl = (MyTabControl)Control;
System.Windows.Forms.Control.ControlCollection oldTabs =
ParentControl.Controls;

if (ParentControl.SelectedIndex < 0) return;

RaiseComponentChanging(TypeDescriptor.GetPropertie s(ParentControl)["TabPages"]);

DesignerHost.DestroyComponent(ParentControl.TabPag es[ParentControl.SelectedIndex]);

RaiseComponentChanged(TypeDescriptor.GetProperties (ParentControl)["TabPages"],
oldTabs, ParentControl.TabPages);

SelectionService.SetSelectedComponents(new IComponent[] {
ParentControl }, SelectionTypes.Auto);

SetVerbs();

}

private void SetVerbs()
{
MyTabControl ParentControl = (MyTabControl)Control;

switch (ParentControl.TabPages.Count)
{
case 0:
Verbs[1].Enabled = false;
break;
default:
Verbs[1].Enabled = true;
break;
}
}

private const int WM_NCHITTEST = 0x84;

private const int HTTRANSPARENT = -1;
private const int HTCLIENT = 1;

protected override void WndProc(ref System.Windows.Forms.Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCHITTEST)
{
//select tabcontrol when Tabcontrol clicked outside of
TabItem.
if (m.Result.ToInt32() == HTTRANSPARENT)
m.Result = (IntPtr)HTCLIENT;
}

}

private enum TabControlHitTest
{
TCHT_NOWHERE = 1,
TCHT_ONITEMICON = 2,
TCHT_ONITEMLABEL = 4,
TCHT_ONITEM = TCHT_ONITEMICON | TCHT_ONITEMLABEL
}

private const int TCM_HITTEST = 0x130D;

private struct TCHITTESTINFO
{
public System.Drawing.Point pt;
public TabControlHitTest flags;
}

protected override bool GetHitTest(System.Drawing.Point point)
{
if (this.SelectionService.PrimarySelection == this.Control)
{
TCHITTESTINFO hti = new TCHITTESTINFO();

hti.pt = this.Control.PointToClient(point);
hti.flags = 0;

System.Windows.Forms.Message m = new
System.Windows.Forms.Message();
m.HWnd = this.Control.Handle;
m.Msg = TCM_HITTEST;

IntPtr lparam =
System.Runtime.InteropServices.Marshal.AllocHGloba l(System.Runtime.InteropServices.Marshal.SizeOf(ht i));
System.Runtime.InteropServices.Marshal.StructureTo Ptr(hti,
lparam, false);
m.LParam = lparam;

base.WndProc(ref m);
System.Runtime.InteropServices.Marshal.FreeHGlobal (lparam);

if (m.Result.ToInt32() != -1)
return hti.flags != TabControlHitTest.TCHT_NOWHERE;

}

return false;
}

protected override void
OnPaintAdornments(System.Windows.Forms.PaintEventA rgs pe)
{
//Don't want DrawGrid dots.
}

//Fix the AllSizable selectionrule on DockStyle.Fill
public override System.Windows.Forms.Design.SelectionRules
SelectionRules
{
get
{
if (Control.Dock == System.Windows.Forms.DockStyle.Fill)
return
System.Windows.Forms.Design.SelectionRules.Visible ;
return base.SelectionRules;
}
}

}

}
///

HTH
Thanks Mick , where did you learn all this ?, is there a book I can buy which explains how to create custom designers ?, once again
thanks very much for your comprehensive solution
Dec 15 '06 #5

P: n/a
"Pete Kane" <pj**********@uku.co.ukwrote in message
news:uq**************@TK2MSFTNGP03.phx.gbl...
Mick Doherty wrote:
>>
<--SNIP-->
>>
Thanks Mick , where did you learn all this ?, is there a book I can buy
which explains how to create custom designers ?
The only .Net book that I have ever used was '.Net Windows Forms Custom
Controls'. ISBN: 0-672-32333-8
I couldn't say how that compares with other books, but it only briefly goes
into Designers. I really only used the book to help convert my existing
VBClassic coding skills to .Net.

If I can't find an answer or a hint within Google Groups then I generally
get direction via the help files or the MSDN Library and then just play
until it works. This is the most satisfying way to do it, but it can also be
quite stressful.

I probably spend far too much time on the PC programming, and not enough
down the pub ;-)

thanks very much for your comprehensive solution
You're welcome.

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html
Dec 15 '06 #6

P: n/a
I think there is a market for a book on the designer / class attributes
- you could write it in the pub ! , thanks again
Mick Doherty wrote:
"Pete Kane" <pj**********@uku.co.ukwrote in message
news:uq**************@TK2MSFTNGP03.phx.gbl...
>>Mick Doherty wrote:
<--SNIP-->
>>Thanks Mick , where did you learn all this ?, is there a book I can buy
which explains how to create custom designers ?


The only .Net book that I have ever used was '.Net Windows Forms Custom
Controls'. ISBN: 0-672-32333-8
I couldn't say how that compares with other books, but it only briefly goes
into Designers. I really only used the book to help convert my existing
VBClassic coding skills to .Net.

If I can't find an answer or a hint within Google Groups then I generally
get direction via the help files or the MSDN Library and then just play
until it works. This is the most satisfying way to do it, but it can also be
quite stressful.

I probably spend far too much time on the PC programming, and not enough
down the pub ;-)
>>thanks very much for your comprehensive solution


You're welcome.
Dec 16 '06 #7

P: n/a
Mick Doherty wrote:
"Pete Kane" <pj**********@uku.co.ukwrote in message
news:uq**************@TK2MSFTNGP03.phx.gbl...
>Mick Doherty wrote:
<--SNIP-->
>Thanks Mick , where did you learn all this ?, is there a book I can buy
which explains how to create custom designers ?

The only .Net book that I have ever used was '.Net Windows Forms Custom
Controls'. ISBN: 0-672-32333-8
I couldn't say how that compares with other books, but it only briefly goes
into Designers. I really only used the book to help convert my existing
VBClassic coding skills to .Net.

If I can't find an answer or a hint within Google Groups then I generally
get direction via the help files or the MSDN Library and then just play
until it works. This is the most satisfying way to do it, but it can also be
quite stressful.

I probably spend far too much time on the PC programming, and not enough
down the pub ;-)

>thanks very much for your comprehensive solution

You're welcome.
Hello Mick, don't know if you're still following this thread but here goes, I have my class working very well now in the IDE, what I
would like to be able to do is control the "Name" it is given at design time - it's not a huge issue but would save some time
renaming, no matter what I try my TabPages are always "Named" e.g. PJKBaseTabPage1 etc..., my OnAddPage() is as shown below, the
"Text" property takes the new value but the "Name" doesn't , any ideas ?, thanks

void OnAddPage(Object sender, EventArgs e)
{
PJKBaseTabControl ParentControl = (PJKBaseTabControl)Control;
System.Windows.Forms.Control.ControlCollection oldTabs = ParentControl.Controls;

RaiseComponentChanging(TypeDescriptor.GetPropertie s(ParentControl)["TabPages"]);

PJKBaseTabPage P = (PJKBaseTabPage)(DesignerHost.CreateComponent(type of(PJKBaseTabPage)));

int NewPageNumber = ParentControl.TabCount + 1;
string PageName = "Page " + NewPageNumber.ToString();
P.Text = PageName;
ParentControl.TabPages.Add(P);
RaiseComponentChanged(TypeDescriptor.GetProperties (ParentControl)["TabPages"], oldTabs, ParentControl.TabPages);
ParentControl.TabPages[NewPageNumber - 1].Name = PageName.Remove(PageName.LastIndexOf(" "), 1);
ParentControl.SelectedTab = P;
SetVerbs();
}
Dec 19 '06 #8

P: n/a
You were almost there ;-)

The IDesignerHost.CreateComponent() method has an overload that takes a Name
value.

int NewPageNumber = ParentControl.TabCount + 1;
PJKBaseTabPage P =
(PJKBaseTabPage)(DesignerHost.CreateComponent(type of(PJKBaseTabPage), "Page"
+ NewPageNumber.ToString()));
P.Text = PageName;
ParentControl.TabPages.Add(P);

However, this will only result in those tabpages added via the 'Add Tab'
verb/smart tag to be custom named and of course, if you remove a tabpage,
the naming algorithm will fail.

I haven't actually tried to modify the Name of the control/component being
added before, so I don't have the correct answer off the top of my head. I
probably won't have a chance to look into it this side of Christmas now, but
if you've not found the answer by the time I do get a chance to look, I'll
post it here.

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html
"Pete Kane" <pj**********@uku.co.ukwrote in message
news:uL*************@TK2MSFTNGP06.phx.gbl...
Mick Doherty wrote:
>"Pete Kane" <pj**********@uku.co.ukwrote in message
news:uq**************@TK2MSFTNGP03.phx.gbl...
>>Mick Doherty wrote:
<--SNIP-->
>>Thanks Mick , where did you learn all this ?, is there a book I can buy
which explains how to create custom designers ?

The only .Net book that I have ever used was '.Net Windows Forms Custom
Controls'. ISBN: 0-672-32333-8
I couldn't say how that compares with other books, but it only briefly
goes into Designers. I really only used the book to help convert my
existing VBClassic coding skills to .Net.

If I can't find an answer or a hint within Google Groups then I generally
get direction via the help files or the MSDN Library and then just play
until it works. This is the most satisfying way to do it, but it can also
be quite stressful.

I probably spend far too much time on the PC programming, and not enough
down the pub ;-)

>>thanks very much for your comprehensive solution

You're welcome.
Hello Mick, don't know if you're still following this thread but here
goes, I have my class working very well now in the IDE, what I would like
to be able to do is control the "Name" it is given at design time - it's
not a huge issue but would save some time renaming, no matter what I try
my TabPages are always "Named" e.g. PJKBaseTabPage1 etc..., my OnAddPage()
is as shown below, the "Text" property takes the new value but the "Name"
doesn't , any ideas ?, thanks

void OnAddPage(Object sender, EventArgs e)
{
PJKBaseTabControl ParentControl = (PJKBaseTabControl)Control;
System.Windows.Forms.Control.ControlCollection oldTabs =
ParentControl.Controls;
RaiseComponentChanging(TypeDescriptor.GetPropertie s(ParentControl)["TabPages"]);

PJKBaseTabPage P =
(PJKBaseTabPage)(DesignerHost.CreateComponent(type of(PJKBaseTabPage)));

int NewPageNumber = ParentControl.TabCount + 1;
string PageName = "Page " + NewPageNumber.ToString();
P.Text = PageName;
ParentControl.TabPages.Add(P);

RaiseComponentChanged(TypeDescriptor.GetProperties (ParentControl)["TabPages"],
oldTabs, ParentControl.TabPages);
ParentControl.TabPages[NewPageNumber - 1].Name =
PageName.Remove(PageName.LastIndexOf(" "), 1);
ParentControl.SelectedTab = P;
SetVerbs();
}

Dec 19 '06 #9

P: n/a
Mick Doherty wrote:
You were almost there ;-)

The IDesignerHost.CreateComponent() method has an overload that takes a Name
value.

int NewPageNumber = ParentControl.TabCount + 1;
PJKBaseTabPage P =
(PJKBaseTabPage)(DesignerHost.CreateComponent(type of(PJKBaseTabPage), "Page"
+ NewPageNumber.ToString()));
P.Text = PageName;
ParentControl.TabPages.Add(P);

However, this will only result in those tabpages added via the 'Add Tab'
verb/smart tag to be custom named and of course, if you remove a tabpage,
the naming algorithm will fail.

I haven't actually tried to modify the Name of the control/component being
added before, so I don't have the correct answer off the top of my head. I
probably won't have a chance to look into it this side of Christmas now, but
if you've not found the answer by the time I do get a chance to look, I'll
post it here.
Thanks Mick, last question ? if my TabPage took a parameter how could I pass it using CreateComponent() ?, cheers
Dec 20 '06 #10

P: n/a
Do you mean a parameter for the Name?

I don't think that this is possible, besides which, this is the wrong place
to change the name as the custom CollectionEditor does not have access to
it.

Just out of curiosity, why do you not want to use the default naming
standard?

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html
"Pete Kane" <pj**********@uku.co.ukwrote in message
news:eV**************@TK2MSFTNGP02.phx.gbl...
Mick Doherty wrote:
>You were almost there ;-)

The IDesignerHost.CreateComponent() method has an overload that takes a
Name value.

int NewPageNumber = ParentControl.TabCount + 1;
PJKBaseTabPage P =
(PJKBaseTabPage)(DesignerHost.CreateComponent(typ eof(PJKBaseTabPage),
"Page" + NewPageNumber.ToString()));
P.Text = PageName;
ParentControl.TabPages.Add(P);

However, this will only result in those tabpages added via the 'Add Tab'
verb/smart tag to be custom named and of course, if you remove a tabpage,
the naming algorithm will fail.

I haven't actually tried to modify the Name of the control/component
being added before, so I don't have the correct answer off the top of my
head. I probably won't have a chance to look into it this side of
Christmas now, but if you've not found the answer by the time I do get a
chance to look, I'll post it here.

Thanks Mick, last question ? if my TabPage took a parameter how could I
pass it using CreateComponent() ?, cheers

Dec 21 '06 #11

P: n/a
Mick Doherty wrote:
Do you mean a parameter for the Name?

I don't think that this is possible, besides which, this is the wrong place
to change the name as the custom CollectionEditor does not have access to
it.

Just out of curiosity, why do you not want to use the default naming
standard?
Hi Mick, Xmas over this is the first day back on the PC so just read
your message, I'm just curious about the parameter passing to the
constructor (maybe passing in a usercontrol as a param) but I suppose
this belongs in the code of the app, you have really whetted my interest
in customising the designers as I also use Visual Foxpro and you can
write your own builders which are similar to what we're doing here , get
cracking on the book ! HNY , Pete
Dec 30 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.