在设计时添加自定义TabPages [英] Adding custom TabPages at design time

查看:95
本文介绍了在设计时添加自定义TabPages的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,有没有人知道如何在设计时添加自己类的TabPages?理想情况下,当添加一个新的TabControl时,它会包含我自己的类的标签页,我知道你可以通过ListView列实现这一点,所以它应该是可行的,谢谢

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

推荐答案

将ToolBoxItemAttribute添加到您的自定义TabPage类中,以便您可以将
从工具箱中拖放,或者从TabControl继承并提供

它是一个自定义的TabPageCollection。


你会在我的TabControls提示页面上找到后者的一个例子
http://www.dotnetrix.co.uk/tabcontrols.html


对于VS2005,你需要将一个ScrollableControlDesigner添加到自定义的

TabPage中,否则它将在IDE中出现异常。


-

Mick Doherty
http://dotnetrix.co。 uk / nothing.html

Pete凯恩与QUOT; < pj ********** @ uku.co.ukwrote in message

news:eG ************* @ TK2MSFTNGP02.phx。 gbl ...
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...

大家好,有没有人知道如何在设计中添加自己类的TabPages

时间?理想情况下,当添加一个新的TabControl时,它将包含我自己的类的标签页

,我知道你可以使用ListView列实现这一点,所以它应该是可行的
,谢谢
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



Mick Doherty写道:
Mick Doherty wrote:

将ToolBoxItemAttribute添加到自定义TabPage类这样你就可以从工具箱中拖放它了,或者从TabControl继承它,并给它一个自定义的TabPageCollection




你会在我的TabControls提示页面上找到后者的例子
http://www.dotnetrix.co.uk/tabcontrols.html


对于VS2005,您需要将ScrollableControlDesigner添加到自定义

TabPage或它在IDE中行为不端。
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,它(你的样本tabcontrol与自定义tabpages)看起来非常令人印象深刻e但我需要在默认情况下添加我的自定义

页面的哪些部分(即在IDE中添加tabcontrol时以及在设计器中添加后续页面时?非常感谢

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


你需要大部分代码。


实际的TabControl和Custom TabPage类不是太广泛。在

命令修改DesignerVerbs(添加标签,删除标签),你必须提供一个

自定义TabControlDesigner,在VS2005中你必须提供一个自定义

TabPageDesigner。


TabPageDesigner非常简单,因为它只需要指定为

ScrollableControlDesigner,但TabControlDesigner非常复杂,因为

控件需要在DesignTime以及运行时导航,并且

System.Windows.Forms.Design.TabControlDesigner无法继承。


我已经用它最基本的形式创建了一个例子,但这里的代码数量仍然是公平的




System.Windows.Forms.TabPage在VS2005 IDE中会出错,所以我在
创建了一个没有特殊功能的基本TabPage类。它只是一个

继承的System.Windows.Forms.TabPage,它使用ScrollControlDesigner。

所有的自定义TabPages都应该从这个类继承。对于示例的

目的,我创建了一个RandomColorTabPage,只是为了显示

的实现。


添加动词/ SmartTag将添加一个基本的TabPage。

如果您只需单击Add

按钮,CollectionEditor将添加一个基本的TabPage,但该按钮有一个下拉列表,允许您选择一个

随机添加RandomColorTabPage。

要更改将在下拉列表中显示的TabPage类型,只需

修改MyTabPageCollectionEditor'' ■CreateNewItemTypes()方法返回

你想要的Type Array。

要更改通过Add Tab动词添加的TabPage类型,只需修改

在TabControlDesigner的OnAddPage()方法中键入。

在运行时,您可以添加System.Windows.Forms.TabPage的实例而不需要

惩罚。 />

这里是代码:(请注意,您需要添加对

System.Design.dll的引用)

\\\

使用System;

使用System.ComponentModel;

使用System.ComponentModel.Design;

使用System.Drawing.Design;


命名空间Dotnetrix.Examples

{

[Designer(typeof) (MyTabControlDesigner))]

公共类MyTabControl:System.Windows.Forms.TabControl

{

CreateNewItemTypes()

{

返回新类型[] {typeof(TabPage),

typeof(RandomColorTabPage)};

} $ / $

}


[Designer(typeof(System.Windows.Forms。 Design.Scroll ableControlDesigner))]

公共类TabPage:System.Windows.Forms.TabPage

{

public TabPage()

:基数()

{

}

}


公共课RandomColorTabPage:TabPage

{

public RandomColorTabPage()

:base()

{

this.BackColor = RandomColor();

}


私有静态随机ColorRandomizer = new Random();


私人系统.Drawing.Color RandomColor()

{

返回System.Drawing.Color.FromArgb(ColorRandomizer.Next(256),

ColorRandomizer。下一步(256),

ColorRandomizer.Next(256));

}

}

内部类MyTabControlDesigner :

System.Windows.Forms.Design.ParentControlDesigner

{


#region私人实例变量


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,ve rb2});

}


#region属性


公共覆盖DesignerVerbCollection动词

{

get

{

if(m_verbs.Count == 2)

{

MyTabControl MyControl =(MyTabControl)控制;

if(MyControl.TabCount 0)

{

m_verbs [1]。 Enabled = true;

}

else

{

m_verbs [1] .Enabled = false;

}

}

返回m_verbs;

}

}


public IDesignerHost DesignerHost

{

get

{

if(m_DesignerHost == null)

m_DesignerHost =

(IDesignerHost)(GetService(typeof(IDesignerHost)));


返回m_DesignerHost;

}

}


公共ISelectionService SelectionService

{

get

{

if(m_SelectionService == null)

m_SelectionService =

(ISe lectionService)(this.GetService(typeof(ISelect ionService)));

返回m_SelectionService;

}

}


#endregion


void OnAddPage(Object sender,EventArgs e)

{

MyTabControl ParentControl =( MyTabControl)控制;

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组件(typeof(TabPage)));

P.Text = P.Name;

ParentControl.TabPages.Add(P);


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

oldTabs,ParentControl.TabPages);

ParentControl。 SelectedTab = P;


SetVerbs();


}


void OnRemovePag e(Object sender,EventArgs e)

{

MyTabControl ParentControl =(MyTabControl)Control;

System.Windows.Forms.Control.ControlCollection oldTabs =

ParentControl.Controls;


if(ParentControl.SelectedIndex< 0)返回;


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


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


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

oldTabs,ParentControl.TabPages );


SelectionService.SetSelectedComponents(新IComponent [] {

ParentControl},SelectionTypes.Auto);


SetVerbs();


}


private void SetVerbs()

{

MyTabControl ParentControl =(MyTabControl)控件;


开关(ParentControl.TabPages.Count)

{

案例0:

动词[1] .Enabled = false;

break;

默认:

动词[1]。 Enabled = true;

break;

}

}


private const int WM_NCHITTEST = 0x84 ;


私有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)

{

//当Tabcontrol点击外面时选择tabcontrol

TabItem。

if(m.Result.ToInt32()== HTTRANSPARENT)

m.Result =(IntPtr)HTCLIENT;

}


}


私人枚举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;


}


返回false;

}


protected override void

OnPaintAdornments(System.Windows.Forms.PaintEventA rgs pe)

{

//不想要DrawGrid点。

}


//在DockStyle.Fill上修复AllSizable选择规则

公共覆盖System.Windows.Forms.Design.SelectionRules

SelectionRules

{

get

{

if(Control.Dock == System.Windows.Forms.DockStyle.Fill )

返回

System.Windows.Forms.Design.SelectionRules.Visible;

返回base.SelectionRules;

}

}


}


}

///


HTH


-

Mick Doherty
http://dotnetrix.co.uk/nothing.html

Pete Kane < pj ********** @ uku.co.ukwrote in message

news:ez ************** @ TK2MSFTNGP03.phx .gbl ...
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
{

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写道:
Mick Doherty wrote:

>将ToolBoxItemAttribute添加到您的自定义TabPage类,以便您可以从工具箱中拖放它,或者从TabControl继承并
给它一个自定义的TabPageCollection。

你会找到一个例子后者在我的TabControls提示页面上
http://www.dotnetrix。 co.uk/tabcontrols.html

对于VS2005,你需要在自定义的
TabPage中添加一个ScrollableControlDesigner,否则它会在IDE中出错。
>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,它(你的样本tabcontrol与自定义tabpages)看起来非常好b / b
令人印象深刻但我需要哪些部分才能添加我的自定义页面/>
默认值(即添加tabcont时IDE中的rol)以及在设计器中添加

后续页面时?非常感谢


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



这篇关于在设计时添加自定义TabPages的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆