最近研究了一下如何将第三方控件嵌入到ToolStrip控件中,并能提供Design-Time下的支持.
下面将详细讲解如何把系统的MonthCalendar控件嵌入到ToolStrip控件中.
以下的两幅图片显示了最终的样子.
Run-Time下的样子
Design-Time下的样子
如何将第三方控件嵌入到ToolStrip
微软实现了一个ToolStripControlHost类, 它是ToolStripComboBox, ToolStripTextBox, 和 ToolStripProgressBar等的基类. ToolStripControlHost提供了将第三方控件嵌入ToolStrip的能力. 我们可以用两种方式使用它:
一, 我们可以直接将继承自Control类的第三方控件作为ToolStripControlHost的构造函数的参数构造一个ToolStripControlHost实例, 将这个实例直接作为ToolStrip的Item加到ToolStrip的Items集合中使用即可.
1 |
private void Form2_Load( object sender, EventArgs e) |
2 |
{ |
3 |
MonthCalendar monthCalendar = new MonthCalendar(); |
4 |
monthCalendar.FirstDayOfWeek = Day.Monday; |
5 |
this .toolStrip1.Items.Add( new ToolStripControlHost(monthCalendar)); |
6 |
} |
二, 从ToolStripControlHost派生, 在继承类默认参构造函数中将第三方控件作为参数调用基类的有参构造函数. 这种方式可以很容易的在继承类中暴露属性,方法和事件,便于访问.
实现步骤如下:
1, 扩展 ToolStripControlHost。实现一个调用传入所需控件的基类构造函数的默认构造函数。
1 |
public ToolStripMonthCalendar() : base ( new MonthCalendar()) |
2 |
{ |
3 |
|
4 |
} |
2, 声明一个与包装控件相同类型的属性,并在属性访问器中返回 Control 作为正确类型的控件。
1 |
public MonthCalendar MonthCalendarControl |
2 |
{ |
3 |
get |
4 |
{ |
5 |
return base .Control as MonthCalendar; |
6 |
} |
7 |
} |
3, 使用扩展类中的属性和方法公开包装控件的其他常用属性和方法。
01 |
// Expose the MonthCalendar.FirstDayOfWeek as a property. |
02 |
public Day FirstDayOfWeek |
03 |
{ |
04 |
get |
05 |
{ |
06 |
return this .MonthCalendarControl.FirstDayOfWeek; |
07 |
} |
08 |
set |
09 |
{ |
10 |
value = this .MonthCalendarControl.FirstDayOfWeek; |
11 |
} |
12 |
} |
13 |
|
14 |
|
15 |
// Expose the AddBoldedDate method. |
16 |
public void AddBoldedDate(DateTime dateToBold) |
17 |
{ |
18 |
this .MonthCalendarControl.AddBoldedDate(dateToBold); |
19 |
} |
4, 也可以选择重写 OnSubscribeControlEvents 和 OnUnsubscribeControlEvents 方法,并添加要公开的控件事件。
01 |
// Subscribe and unsubscribe the control events you wish to expose. |
02 |
protected override void OnSubscribeControlEvents(Control c) |
03 |
{ |
04 |
// Call the base so the base events are connected. |
05 |
base .OnSubscribeControlEvents(c); |
06 |
|
07 |
// Cast the control to a MonthCalendar control. |
08 |
MonthCalendar monthCalendarControl = (MonthCalendar)c; |
09 |
|
10 |
// Add the event. |
11 |
monthCalendarControl.DateChanged += new DateRangeEventHandler(OnDateChanged); |
12 |
} |
13 |
|
14 |
protected override void OnUnsubscribeControlEvents(Control c) |
15 |
{ |
16 |
// Call the base method so the basic events are unsubscribed. |
17 |
base .OnUnsubscribeControlEvents(c); |
18 |
|
19 |
|
20 |
// Cast the control to a MonthCalendar control. |
21 |
MonthCalendar monthCalendarControl = (MonthCalendar)c; |
22 |
|
23 |
|
24 |
// Remove the event. |
25 |
monthCalendarControl.DateChanged -= new DateRangeEventHandler(OnDateChanged); |
26 |
} |
5, 为要公开的事件提供必要的包装。
01 |
// Declare the DateChanged event. |
02 |
|
03 |
public event DateRangeEventHandler DateChanged; |
04 |
|
05 |
|
06 |
// Raise the DateChanged event. |
07 |
|
08 |
private void OnDateChanged( object sender, DateRangeEventArgs e) |
09 |
{ |
10 |
if (DateChanged != null ) |
11 |
{ |
12 |
DateChanged( this , e); |
13 |
} |
14 |
} |
完整的示例请参见MSDN(http://msdn2.microsoft.com/en-us/library/9k5etstz.aspx ).
如何提供设计时的支持
1, 为从ToolStripControlHost继承的类添加ToolStripItemDesignerAvailabilityAttribute标签.
它可以使ToolStrip在Design-Time下能够找到从ToolStripControlHost继承的第三方控件, 直接效果就是第三方控件在下拉菜单中可以直接列举出来. 另外,除了可以将第三方控件嵌入ToolStrip外, 我们还可以直接将第三方控件嵌入到ContextMenuStrip, MenuStrip和StatusStrip中.
ToolStripItemDesignerAvailability枚举成员如下:
成员名称 |
说明 |
All |
指定所有控件均可见。 |
ContextMenuStrip |
指定 ContextMenuStrip 是可见的。 |
MenuStrip |
指定 MenuStrip 是可见的。 |
None |
指定无任何控件可见。 |
StatusStrip |
指定 StatusStrip 是可见的。 |
ToolStrip |
指定 ToolStrip 是可见的。 |
2, 为继承的控件添加ToolboxBitmapAttribute标签改变默认Icon.
01 |
[ToolboxBitmap( typeof (MonthCalendar))] |
02 |
[DefaultProperty( "Value" )] |
03 |
[ToolStripItemDesignerAvailability( |
04 |
ToolStripItemDesignerAvailability.ContextMenuStrip | |
05 |
ToolStripItemDesignerAvailability.MenuStrip | |
06 |
ToolStripItemDesignerAvailability.StatusStrip | |
07 |
ToolStripItemDesignerAvailability.ToolStrip)] |
08 |
public class ToolStripMonthCalendar : ToolStripControlHost |
09 |
{ |
10 |
//TODO: ...... |
11 |
} |
The End