DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

自作したToolStripItemをVisual Studioのデザイナで表示する

注意:ここで紹介している方法は、.NET Framework 2.0以降でのみ使用できます。

Visual Studioのデザイナでは、ToolStripの端に新しいアイテム(ToolStripItem)を追加するためのボタンが表示され、これを使って簡単にアイテムを追加することができます。しかし、「ToolStrip(ツールバー、メニュー、ステータスバー)に任意のコントロールを配置する」で紹介したような自作のToolStripItemの場合はVisual Studioのデザイナに表示されないため、自分でコードを書いてToolStripに配置しなければなりません。ここでは、自作ToolStripItemがVisual Studioのデザイナに表示されるようにする方法を紹介します。

ToolStrip

自作のToolStripItemをデザイナで表示してToolStripに追加できるようにするには、ToolStripItemDesignerAvailability属性を使用します。例えば、次のようなToolStripNumericUpDownを定義すれば、フォームデザイナのToolStripとStatusStripでこのToolStripNumericUpDownを追加することができるようになります。

VB.NET
コードを隠すコードを選択
<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
C#
コードを隠すコードを選択
[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の大きさである必要があります。

VB.NET
コードを隠すコードを選択
<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
C#
コードを隠すコードを選択
[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属性を使って画像を指定することもできます。この方法では、画像のほかに、表示名や説明を変更することもできます。

VB.NET
コードを隠すコードを選択
<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
C#
コードを隠すコードを選択
[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が表示されない

DateTimePickerコントロールをホストするToolStripControlHostは、Visual StudioのフォームデザイナでToolStripに追加しようとしても、追加できません。この回避法は、幾つか報告されています。

Toolbar のアイテムを拡張する」では、DefaultPropertyAttribute属性をマーク方法が紹介されています。

VB.NET
コードを隠すコードを選択
<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
C#
コードを隠すコードを選択
[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でも大丈夫のようです。

VB.NET
コードを隠すコードを選択
<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
C#
コードを隠すコードを選択
[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プロパティをオーバーライドする方法が紹介されています。

VB.NET
コードを隠すコードを選択
<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
C#
コードを隠すコードを選択
[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メソッドを呼び出す方法が紹介されています。

VB.NET
コードを隠すコードを選択
<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
C#
コードを隠すコードを選択
[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で、フォームデザイナの表示がおかしくなる

ここで紹介した方法をVisual Studio 2008で行うと、フォームデザイナがおかしくなるという問題があります。この回避法は、今のところ、ToolStripControlHostから派生した自作のToolStripItemを別プロジェクトのクラスライブラリ(DLL)として作成し、使用する方法しか分かっていません。

  • 履歴:
  • 2010/9/23 「DateTimePickerをホストするToolStripControlHostが表示されない」と「Visual Studio 2008で、フォームデザイナの表示がおかしくなる」を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。