注意:ここで紹介している方法は、.NET Framework 2.0以降でのみ使用できます。
Visual Studioのデザイナでは、ToolStripの端に新しいアイテム(ToolStripItem)を追加するためのボタンが表示され、これを使って簡単にアイテムを追加することができます。しかし、「ToolStrip(ツールバー、メニュー、ステータスバー)に任意のコントロールを配置する」で紹介したような自作のToolStripItemの場合はVisual Studioのデザイナに表示されないため、自分でコードを書いてToolStripに配置しなければなりません。ここでは、自作ToolStripItemがVisual Studioのデザイナに表示されるようにする方法を紹介します。
自作のToolStripItemをデザイナで表示してToolStripに追加できるようにするには、ToolStripItemDesignerAvailability属性を使用します。例えば、次のようなToolStripNumericUpDownを定義すれば、フォームデザイナのToolStripとStatusStripでこのToolStripNumericUpDownを追加することができるようになります。
<System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _ System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip _ Or System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)> _ Public Class ToolStripNumericUpDown Inherits System.Windows.Forms.ToolStripControlHost Public Sub New() MyBase.New(New System.Windows.Forms.NumericUpDown()) End Sub End Class
[System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip | System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)] public class ToolStripNumericUpDown : System.Windows.Forms.ToolStripControlHost { public ToolStripNumericUpDown() : base(new System.Windows.Forms.NumericUpDown()) { } }
さらに、デザイナでToolStripItemを追加する時のメニューで左側に表示される画像を変更するには、ToolboxBitmap属性を使います。(画像が指定されていないと、上図のように歯車の画像が表示されます。)
次の例では、「OpenFolder.bmp」という画像が「埋め込まれたリソース」としてアセンブリに埋め込まれている時に、これをToolStripNumericUpDownの画像としています。なお画像は、16x16の大きさである必要があります。
<System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _ System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip _ Or System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip), _ System.Drawing.ToolboxBitmap(GetType(ToolStripNumericUpDown), "OpenFolder.bmp")> _ Public Class ToolStripNumericUpDown Inherits System.Windows.Forms.ToolStripControlHost Public Sub New() MyBase.New(New System.Windows.Forms.NumericUpDown()) End Sub End Class
[System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip | System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)] [System.Drawing.ToolboxBitmap(typeof(ToolStripNumericUpDown), "OpenFolder.bmp")] public class ToolStripNumericUpDown : System.Windows.Forms.ToolStripControlHost { public ToolStripNumericUpDown() : base(new System.Windows.Forms.NumericUpDown()) { } }
これとは別に、ToolboxItem属性を使って画像を指定することもできます。この方法では、画像のほかに、表示名や説明を変更することもできます。
<System.ComponentModel.ToolboxItem(GetType(NumericUpDownToolboxItem)), _ System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _ System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)> _ Public Class ToolStripNumericUpDown Inherits System.Windows.Forms.ToolStripControlHost Public Sub New() MyBase.New(New System.Windows.Forms.NumericUpDown()) End Sub End Class Public Class NumericUpDownToolboxItem Inherits System.Drawing.Design.ToolboxItem Public Sub New() End Sub Public Overrides Sub Initialize(ByVal type As Type) MyBase.Initialize(type) '説明 Me.Description = "数字を入力できます。" '表示名 Me.DisplayName = "数字入力" '画像 Me.Bitmap = New System.Drawing.Bitmap( _ GetType(NumericUpDownToolboxItem), "OpenFolder.bmp") End Sub End Class
[System.ComponentModel.ToolboxItem(typeof(NumericUpDownToolboxItem))] [System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)] public class ToolStripNumericUpDown : System.Windows.Forms.ToolStripControlHost { public ToolStripNumericUpDown() : base(new System.Windows.Forms.NumericUpDown()) { } } public class NumericUpDownToolboxItem : System.Drawing.Design.ToolboxItem { public NumericUpDownToolboxItem() { } public override void Initialize(System.Type type) { base.Initialize(type); //説明 this.Description = "数字を入力できます。"; //表示名 this.DisplayName = "数字入力"; //画像 this.Bitmap = new System.Drawing.Bitmap( typeof(NumericUpDownToolboxItem), "OpenFolder.bmp"); } }
DateTimePickerコントロールをホストするToolStripControlHostは、Visual StudioのフォームデザイナでToolStripに追加しようとしても、追加できません。この回避法は、幾つか報告されています。
「Toolbar のアイテムを拡張する」では、DefaultPropertyAttribute属性をマーク方法が紹介されています。
<System.ComponentModel.DefaultProperty("Items")> _ <System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _ System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)> _ Public Class ToolStripDateTimePicker Inherits System.Windows.Forms.ToolStripControlHost Public Sub New() MyBase.New(New System.Windows.Forms.DateTimePicker()) End Sub End Class
[System.ComponentModel.DefaultProperty("Items")] [System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)] public class ToolStripDateTimePicker : System.Windows.Forms.ToolStripControlHost { public ToolStripDateTimePicker() : base(new System.Windows.Forms.DateTimePicker()) { } }
また、「Using ToolStripControlHost with DateTimePicker」では、FlowLayoutPanelにDateTimePickerをのせる方法が紹介されています。なお、FlowLayoutPanelでなく、普通のPanelでも大丈夫のようです。
<System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _ System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)> _ Public Class ToolStripDateTimePicker Inherits System.Windows.Forms.ToolStripControlHost Public Sub New() MyBase.New(New System.Windows.Forms.FlowLayoutPanel()) Dim panel As System.Windows.Forms.FlowLayoutPanel = _ DirectCast(Me.Control, System.Windows.Forms.FlowLayoutPanel) panel.BackColor = System.Drawing.Color.Transparent panel.Controls.Add(New System.Windows.Forms.DateTimePicker()) End Sub End Class
[System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)] public class ToolStripDateTimePicker : System.Windows.Forms.ToolStripControlHost { public ToolStripDateTimePicker() : base(new System.Windows.Forms.FlowLayoutPanel()) { System.Windows.Forms.FlowLayoutPanel panel = (System.Windows.Forms.FlowLayoutPanel)this.Control; panel.BackColor = System.Drawing.Color.Transparent; panel.Controls.Add(new System.Windows.Forms.DateTimePicker()); } }
同じページに、Textプロパティをオーバーライドする方法が紹介されています。
<System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _ System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)> _ Public Class ToolStripDateTimePicker Inherits System.Windows.Forms.ToolStripControlHost Public Sub New() MyBase.New(New System.Windows.Forms.DateTimePicker()) End Sub <System.ComponentModel.Browsable(False), _ System.ComponentModel.EditorBrowsable( _ System.ComponentModel.EditorBrowsableState.Never)> _ Public Overrides Property Text() As String Get Return "" End Get Set(ByVal value As String) MyBase.Text = "" End Set End Property End Class
[System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)] public class ToolStripDateTimePicker : System.Windows.Forms.ToolStripControlHost { public ToolStripDateTimePicker() : base(new System.Windows.Forms.DateTimePicker()) { } [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable( System.ComponentModel.EditorBrowsableState.Never)] public override string Text { get { return ""; } set { base.Text = ""; } } }
さらに「ToolStripControlHostとDateTimePicker」では、DateTimePickerのCreateControlメソッドを呼び出す方法が紹介されています。
<System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _ System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)> _ Public Class ToolStripDateTimePicker Inherits System.Windows.Forms.ToolStripControlHost Public Sub New() MyBase.New(CreateControlInstance()) End Sub Private Shared Function CreateControlInstance() As Control Dim c As New DateTimePicker() c.CreateControl() Return c End Function End Class
[System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)] public class ToolStripDateTimePicker : System.Windows.Forms.ToolStripControlHost { public ToolStripDateTimePicker() : base(CreateControlInstance()) { } private static Control CreateControlInstance() { DateTimePicker c = new DateTimePicker(); c.CreateControl(); return c; } }
ここで紹介した方法をVisual Studio 2008で行うと、フォームデザイナがおかしくなるという問題があります。この回避法は、今のところ、ToolStripControlHostから派生した自作のToolStripItemを別プロジェクトのクラスライブラリ(DLL)として作成し、使用する方法しか分かっていません。
(この記事は、「.NETプログラミング研究」で紹介したものを基にしています。)
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。