┏第68号━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃         .NETプログラミング研究         ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ──<メニュー>─────────────────────── ■.NET Tips ・ToolStripに任意のコントロールを配置する ・自作したToolStripItemをVisual Studioのデザイナで表示する ・ToolStripItemの位置をユーザーが変えられるようにする ・あるToolStripItemの右側に指定したToolStripItemが常にあるよう にする ・ToolStripに関する取るに足らないTip -ToolStripItemを表示あるいは非表示にする ToolStripItemが表示されているか調べる -メニューにToolTipを表示 -右端にToolStripItemを配置 -ToolStripButtonやToolStripMenuItemをクリックすると自動的に チェック状態が変化されるようにする -オーバーフローを有効にする -ToolStripItemがオーバーフロー状態になったことを知る -ToolStripの幅に応じてToolStripItemのDisplayStyleを変更する ─────────────────────────────── ─────────────────────────────── ■.NET Tips ─────────────────────────────── 今回も前回に引き続き、ToolStripに関するTipsを紹介します。.NET Framework 2.0の新機能ですので、残念ながら1.0、1.1では使用でき ません。 ─────────────────────────────── ●ToolStripに任意のコントロールを配置する ToolStrip(MenuStrip、ContextMenuStrip、StatusStripなど ToolStripから派生したコントロールを含む)に配置できるコントロー ルは、ToolStripItemクラスから派生したコントロールのみです。. NET Framework 2.0では、ToolStripItemクラスから派生したコントロー ルとして、以下のようなものが用意されています。 ToolStripButton: ツールバーの普通のボタン。画像とテキストが表示できる。主に、 ToolStripで使用される。 ToolStripDropDownButton: 押すとドロップダウンリストが表示されるボタン。Exploreで言えば、 「表示」ボタンのような感じ。主に、ToolStrip、StatusStripで使用 される。 ToolStripSplitButton: ToolStripDropDownButtonと似ているが、こちらはボタンとドロップ ダウンボタンが分かれている。Exploreで言えば、「戻る」や「進む」 ボタンのような感じ。主に、ToolStrip、StatusStripで使用される。 ToolStripLabel: テキストや画像を表示する。コメントやタイトルとして使う。主に、 ToolStrip、StatusStripで使用される。 ToolStripSeparator: グループ分けするセパレータ。主に、ToolStrip、MenuStrip、 ContextMenuStripで使用される。 ToolStripMenuItem: メニューで使われる項目。画像も表示可能。主に、MenuStrip、 ContextMenuStripで使用される。 ToolStripStatusLabel: StatusStripで使われるパネル。テキストや画像を表示できる。主に、 ToolStripで使用される。 ToolStripComboBox: コンボボックスを表示する。主に、ToolStrip、MenuStrip、 ContextMenuStripで使用される。 ToolStripTextBox: テキストボックスを表示する。主に、ToolStrip、MenuStrip、 ContextMenuStripで使用される。 ToolStripProgressBar: ProgressBarを表示する。主に、ToolStrip、StatusStripで使用され る。 注意:「主に...で使用される。」というのは、そのToolStripItemを Visual Studioのデザイナを使って配置することができるToolStripの 種類を示しています。デザイナを使わずに、コードでToolStripに追 加する場合は、その限りではありません。 このように、以前のToolBarとは違い、ToolStripには多くのコントロー ルをのせることができます。 これだけでも十分かもしれませんが、さらに、任意のコントロールを ToolStripにのせるための方法が用意されています。それが、 ToolStripControlHostクラスです。ここではToolStripControlHostを 使用した例として、NumericUpDownコントロールをToolStripにのせる 方法を説明します。 まず、次のようなクラスを作成します。あまりに簡単ですが、これだ けで十分です。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Public Class ToolStripNumericUpDown Inherits ToolStripControlHost Public Sub New() MyBase.New(New NumericUpDown()) End Sub End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ using System.Windows.Forms; public class ToolStripNumericUpDown : ToolStripControlHost { public ToolStripNumericUpDown() : base(new NumericUpDown()) { } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ これを実際にToolStripにのせるには、次のようにします(フォーム クラスに書かれてるものとします)。普通のToolStripItemを ToolStripにのせる場合と同じです。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Private toolStripNumeric1 As ToolStripNumericUpDown Protected Overrides Sub OnLoad(ByVal e As EventArgs) MyBase.OnLoad(e) toolStripNumeric1 = New ToolStripNumericUpDown() ToolStrip1.Items.Add(toolStripNumeric1) End Sub ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ private ToolStripNumericUpDown toolStripNumeric1; protected override void OnLoad(EventArgs e) { base.OnLoad(e); toolStripNumeric1 = new ToolStripNumericUpDown(); toolStrip1.Items.Add(toolStripNumeric1); } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ NumericUpDownコントロールをToolStripにのせることはできましたが、 NumericUpDownコントロールにアクセスするにはどのようにすればよ いのでしょうか?例えば、現在の値(Valueプロパティ)を取得する には、どうしたらいいのでしょうか? ToolStripControlHostがホストしているコントロールは、Controlプ ロパティで取得できるため、次のようなコードで、Valueプロパティ の値を取得できます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Console.WriteLine(CType(toolStripNumeric1.Control, NumericUpDown).Value) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Console.WriteLine(((NumericUpDown)toolStripNumeric1.Control).Value); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ このように、たったこれだけのコードでも十分ですが、 ToolStripNumericUpDownクラスをもう少し改良すると、さらに使いや すくなります。 まず、ホストしているNumericUpDownをプロパティで公開します。ま た、よく使うメソッドやプロパティもToolStripNumericUpDownクラス で公開します。ここでは、NumericUpDownの値を設定、取得するため のValueプロパティを作成します。 さらに、ToolStripNumericUpDownクラス内でNumericUpDownのイベン トを処理する必要があれば、OnSubscribeControlEventsと OnUnsubscribeControlEventsメソッドを使用すると、効率的です。こ こでは、NumericUpDownの値が変化した時に発生するValueChangedイ ベントを追加することにします。 以上のように改良したToolStripNumericUpDownクラスは、次のように なります。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Public Class ToolStripNumericUpDown Inherits ToolStripControlHost '/ '/ コンストラクタ '/ Public Sub New() MyBase.New(New NumericUpDown()) End Sub '/ '/ ホストしているNumericUpDownコントロール '/ Public ReadOnly Property NumericUpDown() As NumericUpDown Get Return CType(Control, NumericUpDown) End Get End Property '/ '/ 値の設定と取得 '/ Public Property Value() As Decimal Get Return NumericUpDown.Value End Get Set(ByVal value As Decimal) NumericUpDown.Value = value End Set End Property 'ホストしているNumericUpDownのイベントをサブスクライブする Protected Overrides Sub OnSubscribeControlEvents( _ ByVal control As Control) MyBase.OnSubscribeControlEvents(control) Dim numControl As NumericUpDown = _ CType(control, NumericUpDown) AddHandler numControl.ValueChanged, _ AddressOf NumericUpDown_OnValueChanged End Sub 'ホストしているNumericUpDownのイベントをアンサブスクライブする Protected Overrides Sub OnUnsubscribeControlEvents( _ ByVal control As Control) MyBase.OnUnsubscribeControlEvents(control) Dim numControl As NumericUpDown = _ CType(control, NumericUpDown) RemoveHandler numControl.ValueChanged, _ AddressOf NumericUpDown_OnValueChanged End Sub '/ '/ 値が変化した '/ Public Event ValueChanged As EventHandler 'ValueChangedイベントを発生 Private Sub NumericUpDown_OnValueChanged( _ ByVal sender As Object, ByVal e As EventArgs) RaiseEvent ValueChanged(Me, e) End Sub End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ using System.Windows.Forms; public class ToolStripNumericUpDown : ToolStripControlHost { /// /// コンストラクタ /// public ToolStripNumericUpDown() : base(new NumericUpDown()) { } /// /// ホストしているNumericUpDownコントロール /// public NumericUpDown NumericUpDown { get { return (NumericUpDown)Control; } } /// /// 値の設定と取得 /// public decimal Value { get { return NumericUpDown.Value; } set { NumericUpDown.Value = value; } } //ホストしているNumericUpDownのイベントをサブスクライブする protected override void OnSubscribeControlEvents(Control control) { base.OnSubscribeControlEvents(control); NumericUpDown numControl = (NumericUpDown)control; numControl.ValueChanged += new EventHandler(NumericUpDown_OnValueChanged); } //ホストしているNumericUpDownのイベントをアンサブスクライブする protected override void OnUnsubscribeControlEvents(Control control) { base.OnUnsubscribeControlEvents(control); NumericUpDown numControl = (NumericUpDown)control; numControl.ValueChanged -= new EventHandler(NumericUpDown_OnValueChanged); } /// /// 値が変化した /// public event EventHandler ValueChanged; //ValueChangedイベントを発生 private void NumericUpDown_OnValueChanged(object sender, EventArgs e) { if (ValueChanged != null) { ValueChanged(this, e); } } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 改良したToolStripNumericUpDownクラスの使い方は、次のようになり ます(フォームクラスに書かれてるものとします)。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Private toolStripNumeric1 As ToolStripNumericUpDown Protected Overrides Sub OnLoad(ByVal e As EventArgs) MyBase.OnLoad(e) 'ToolStripNumericUpDownの作成 toolStripNumeric1 = New ToolStripNumericUpDown() 'toolStripNumeric1の値を変更 toolStripNumeric1.Value = 5 'ValueChangedイベントハンドラの追加 AddHandler toolStripNumeric1.ValueChanged, _ AddressOf toolStripNumeric1_ValueChanged 'toolStrip1に追加 ToolStrip1.Items.Add(toolStripNumeric1) End Sub Sub toolStripNumeric1_ValueChanged( _ ByVal sender As Object, ByVal e As EventArgs) Console.WriteLine("値が変わったよ") End Sub ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ private ToolStripNumericUpDown toolStripNumeric1; protected override void OnLoad(EventArgs e) { base.OnLoad(e); //ToolStripNumericUpDownの作成 toolStripNumeric1 = new ToolStripNumericUpDown(); //toolStripNumeric1の値を変更 toolStripNumeric1.Value = 5; //ValueChangedイベントハンドラの追加 toolStripNumeric1.ValueChanged += new EventHandler(toolStripNumeric1_ValueChanged); //toolStrip1に追加 toolStrip1.Items.Add(toolStripNumeric1); } void toolStripNumeric1_ValueChanged(object sender, EventArgs e) { Console.WriteLine("値が変わったよ"); } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 参考: [URL]ToolStripControlHost クラス http://msdn2.microsoft.com/ja-JP/library/system.windows.forms.toolstripcontrolhost.aspx [URL]方法 : ToolStripControlHost を使用して Windows フォーム コントロールをラップする http://msdn2.microsoft.com/ja-jp/library/9k5etstz.aspx ─────────────────────────────── ●自作したToolStripItemをVisual Studioのデザイナで表示する Visual Studioのデザイナでは、ToolStripの端に新しい ToolStripItemを追加するためのボタンが表示され、これを使って簡 単にToolStripItemを追加することができます。しかし、「ToolStrip に任意のコントロールをのせる」で紹介したような自作の ToolStripItemの場合はVisual Studioのデザイナに表示されないため、 コードでToolStripに配置しなければなりません。ここでは、自作 ToolStripItemをVisual Studioのデザイナで表示させる方法を紹介し ます。 自作のToolStripItemをデザイナで表示してToolStripに追加できるよ うにするには、ToolStripItemDesignerAvailability属性を使用しま す。例えば、次のようなToolStripNumericUpDownを定義すれば、フォー ムデザイナのToolStripとStatusStripでこのToolStripNumericUpDown を追加することができるようになります。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ _ Public Class ToolStripNumericUpDown Inherits ToolStripControlHost Public Sub New() MyBase.New(New NumericUpDown()) End Sub End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ [System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip | System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)] public class ToolStripNumericUpDown : ToolStripControlHost { public ToolStripNumericUpDown() : base(new NumericUpDown()) { } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ さらに、デザイナでToolStripItemを追加する時のメニューで左側に 表示される画像を変更するには、ToolboxBitmap属性を使います。(画 像が指定されていないと、歯車の画像が表示されます。) 次の例では、「OpenFolder.bmp」という画像が「埋め込まれたリソー ス」としてアセンブリに埋め込まれている時に、これを ToolStripNumericUpDownの画像としています。なお画像は、16X16の 大きさである必要があります。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ _ Public Class ToolStripNumericUpDown Inherits ToolStripControlHost Public Sub New() MyBase.New(New NumericUpDown()) End Sub End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ [System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip | System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)] [ToolboxBitmap(typeof(ToolStripNumericUpDown), "OpenFolder.bmp")] public class ToolStripNumericUpDown : ToolStripControlHost { public ToolStripNumericUpDown() : base(new NumericUpDown()) { } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ これとは別に、ToolboxItem属性を使って画像を指定することもでき ます。この方法では、画像のほかに、表示名や説明を変更することも できます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ _ Public Class ToolStripNumericUpDown Inherits ToolStripControlHost Public Sub New() MyBase.New(New 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 Bitmap(GetType(NumericUpDownToolboxItem), _ "OpenFolder.bmp") End Sub End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ [System.ComponentModel.ToolboxItem(typeof(NumericUpDownToolboxItem))] [System.Windows.Forms.Design.ToolStripItemDesignerAvailability( System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)] public class ToolStripNumericUpDown : ToolStripControlHost { public ToolStripNumericUpDown() : base(new NumericUpDown()) { } } public class NumericUpDownToolboxItem : System.Drawing.Design.ToolboxItem { public NumericUpDownToolboxItem() { } public override void Initialize(Type type) { base.Initialize(type); //説明 this.Description = "数字を入力できます。"; //表示名 this.DisplayName = "数字入力"; //画像 this.Bitmap = new Bitmap(typeof(NumericUpDownToolboxItem), "OpenFolder.bmp"); } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ─────────────────────────────── ●ToolStripItemの位置をユーザーが変えられるようにする ToolStripのAllowDropプロパティをFalseとして、AllowItemReorder プロパティをTrueとすると、ユーザーがAltキーを押しながら ToolStripItemをドラッグすることにより、その位置を変更すること ができます。 なお、AllowDropプロパティとAllowItemReorderプロパティの両方を Trueとすることはできません。 AllowItemReorderプロパティをTrueとしても移動できない ToolStripItemも多く存在します。ToolStripComboBox、 ToolStripProgressBar、ToolStripTextBoxなど、 ToolStripControlHostを継承したToolStripItemは移動できないよう です。 ToolStripItemの位置を保存、復元する方法は、前々号で説明したと おり、ToolStripManager.SaveSettings、LoadSettingsメソッドを使 います。 このような方法とは別に、ダイアログを表示してToolStripItemの順 番と表示・非表示を変更するサンプルが、MSDNの「ToolStrip のカス タマイズ サンプル」(CustomizeToolStripプロジェクト)にありま す。 [URL]ToolStrip のカスタマイズ サンプル http://msdn2.microsoft.com/ja-jp/library/ms181004.aspx ─────────────────────────────── ●あるToolStripItemの右側に指定したToolStripItemが常にあるよう にする 例えば、ToolStripにToolStripComboBoxが配置されており、その説明 のためにすぐ左側にToolStripLabelを配置した場合、常に ToolStripLabelがToolStripComboBoxの左隣にないと意味不明になっ てしまいます。しかし、ToolStripのAllowItemReorderをTrueとして ユーザーがToolStripItemの位置を自由に変更できる時は、そうなっ てしまう可能性が十分あります。 これを防ぐために、あるToolStripItemの右側に指定した ToolStripItemが常にあるようにする方法を考えてみました。いろい ろな方法が考えられますが、ここではToolStripItemの LocationChangedイベントで処理することにします。 下に示す例では、ToolStripにToolStripLabel(toolStripLabel1)と ToolStripComboBox(toolStripComboBox1)が配置されているとき、 toolStripLabel1の右隣に常にtoolStripComboBox1があるようしてい ます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 'toolStripLabel1のLocationChangedイベントハンドラ Private Sub toolStripLabel1_LocationChanged( _ ByVal sender As Object, ByVal e As EventArgs) _ Handles ToolStripLabel1.LocationChanged Dim item As ToolStripItem = CType(sender, ToolStripItem) If item.Equals(ToolStripLabel1) Then '常に隣にあるべきToolStripItem Dim nextItem As ToolStripItem = ToolStripComboBox1 If Not (nextItem Is Nothing) And _ Not (nextItem.Owner Is Nothing) Then If nextItem.Owner.Items.IndexOf(nextItem) <> _ item.Owner.Items.IndexOf(item) + 1 Then '削除してから挿入する '削除しないと不具合が生じる可能性あり nextItem.Owner.Items.Remove(nextItem) Dim insertIndex As Integer = _ item.Owner.Items.IndexOf(item) + 1 item.Owner.Items.Insert(insertIndex, nextItem) End If End If End If End Sub ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //toolStripLabel1のLocationChangedイベントハンドラ private void toolStripLabel1_LocationChanged( object sender, EventArgs e) { ToolStripItem item = (ToolStripItem)sender; if (item.Equals(toolStripLabel1)) { //常に隣にあるべきToolStripItem ToolStripItem nextItem = toolStripComboBox1; if (nextItem != null && nextItem.Owner != null) { if (nextItem.Owner.Items.IndexOf(nextItem) != item.Owner.Items.IndexOf(item) + 1) { //削除してから挿入する //削除しないと不具合が生じる可能性あり nextItem.Owner.Items.Remove(nextItem); int insertIndex = item.Owner.Items.IndexOf(item) + 1; item.Owner.Items.Insert(insertIndex, nextItem); } } } } ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ この方法は、ユーザーが移動することのできない ToolStripControlHostを継承したToolStripItemをユーザーが移動で きるようにする方法としても使えるかもしれません。 ─────────────────────────────── ●ToolStripに関する取るに足らないTip 最後に、ここで述べるほどでは無いかもしれないつまらないTipをい くつか紹介します。 ★ToolStripItemを表示あるいは非表示にする  ToolStripItemが表示されているか調べる これは、Visibleプロパティを使えばよさそうですが、そう単純では ありません。ToolStripItemにはこれと同じような目的に使用する、 Availableプロパティというものが存在するのです。 両者の違いについてMSDNでは、次のように書かれています(そのまま 引用します)。 Available プロパティは、Visible プロパティとは異なります。 Available が ToolStripItem を表示するかどうかを示すのに対し、 Visible は ToolStripItem およびその親を表示するかどうかを示し ます。Available と Visible のいずれかを true または false に設 定すると、他のプロパティも true または false に設定されます。 [URL]ToolStripItem.Available プロパティ http://msdn2.microsoft.com/ja-JP/library/system.windows.forms.toolstripitem.available.aspx つまり、両者は値の設定に関しては全く同じであり、取得に関しての み異なるということのようです。実際、VS2005のフォームデザイナの プロパティにはVisibleプロパティのみ表示され、Availableプロパテ ィは表示されません。 取得される値がどのように異なるのか、具体的な例で説明しましょう。 例えば、あるToolStripにToolStripItemが配置されており、 ToolStripItemのVisibleとAvailableプロパティがTrueである場合、 そのToolStripのVisibleをFalseに変更すると、ToolStripItemの VisibleもFalseになりますが、AvailableはTrueのままです。また、 ToolStripItemをToolStripから削除した時も、VisibleはFalseになり ますが、AvailableはTrueのままです。 MSDNによると設定に関しては両者に違いがないように思われますが、 実際には違いが見られました。 私の確認した範囲では、別のToolStripItemの子となっている ToolStripMenuItemの場合、AvailableプロパティをFalseにすること により非表示にできますが、VisibleプロパティをFalseにしても非表 示にできませんでした(正確には、VisibleプロパティをFalseにしよ うとしてもできません)。これは、オーバーフローボタンに入った ToolStripItemでもそうであるため、ToolStripItemがオーバーフロー メニューに入っていない時はVisibleプロパティが使えるのに、オー バーフローメニューに入っていると使えなくなってしまうという奇妙 なことになります。ToolStripMenuItemの表示、非表示をプログラム で行う時は、Availableプロパティを使った方が良さそうです。 ★メニューにToolTipを表示 MenuStripやContextMenuStripでは、今までのメニューと違って、 ToolTipを簡単に表示することができます。MenuStripや ContextMenuStripのShowItemToolTipsプロパティをTrueにして、 ToolStripMenuItem.ToolTipTextプロパティにToolTipとして表示する 文字列を指定するだけです。 また、ToolStripItem.AutoToolTipプロパティをTrueとすると、 ToolTipTextが設定されていなくても、代わりにTextに設定された文 字列がToolTipとして表示されます。 なおMSDNには、ToolStrip.ShowItemToolTipsをTrueとしないと ToolTipが表示されないとありますが、MenuStripの場合は ShowItemToolTipsをTrueとしなくても、ToolStripMenuItemにToolTip が表示されました。しかし今後のために、MenuStripでも ShowItemToolTipsをTrueにしておいた方が良いでしょう。 [URL]方法 : ToolStrip コントロールにツールヒントを使用する http://msdn2.microsoft.com/ja-JP/library/ms171703.aspx ★右端にToolStripItemを配置 ToolStripItem.AlignmentプロパティをRightとすることにより、 ToolStripの右端にToolStripItemを配置することができます。これを 使えば、よくある「ヘルプ」だけがメニューの右端にあるようなアプ リケーションも簡単に作れます。 ただし、ToolStrip.LayoutStyleプロパティがTableまたはFlowの場合 は、ToolStripItem.Alignmentプロパティが無視されてしまいます。 ★ToolStripButtonやToolStripMenuItemをクリックすると自動的にチ ェック状態が変化されるようにする ToolStripButtonとToolStripMenuItemにはCheckOnClickプロパティが あり、これをTrueにすることにより、クリックで自動的に状態が変わ るようになります。 ★オーバーフローを有効にする ToolStripの幅をだんだん狭めていき、ToolStripItemが表示しきれな くなると、ToolStripの右側に下矢印のボタンが表示され、そのボタ ンを押すと、ToolStripに表示しきれなくなったToolStripItemがメニ ュー表示されます。この時、この下矢印のボタンを「オーバーフロー ボタン」(あるいは「オーバーフローシェブロン」)といい、 ToolStripItemがオーバーフローボタンのメニューに入ることを「オー バーフロー(状態になった)」といいます。 オーバーフロー機能を有効にするには、ToolStripのCanOverflowプロ パティがTrueで、さらにLayoutStyleプロパティがStackWithOverflow または、HorizontalStackWithOverflowやVerticalStackWithOverflow である必要があります。 また、ToolStripItemをオーバーフローボタンのメニューに移動させ るかをToolStripItem.Overflowプロパティで指定できます。Overflow プロパティがAsNeededの時は必要な時のみ移動させ、Alwaysの時は常 にメニューに表示し、Neverの時はメニューに移動せずに、ToolStrip に収まらなくなったら、表示されなくなります。 補足:MSDNではToolStrip.CanOverflowプロパティの説明を、「 ToolStrip 内の項目をオーバーフロー メニューに送信できるかどう かを示す値を取得または設定します。」としています。「オーバーフ ローメニューに送信」という意味が、オーバーフローメニューに移動 するということであれば、この説明が正しいのか、疑問です。 CanOverflowプロパティがFalseの時、OverflowプロパティがAlwaysの ToolStripItemはToolStripに全く表示されません(ToolStrip. LayoutStyleプロパティがTableまたはFlowの時は、表示されます)。 これは多分、OverflowがAlwaysのToolStripItemがオーバーフローメ ニューに移動したが、オーバーフローボタンが表示されなくなったた め見えなくなったものと考えられます。つまり、CanOverflowプロパ ティはオーバーフローボタンを表示するかどうかを指定するものと解 釈した方が良さそうです。(説明が正しく、動作が間違っている可能 性もありますが。) [URL]方法 : Windows フォームの ToolStrip オーバーフローを管理 する http://msdn2.microsoft.com/ja-JP/library/2z69s2kh.aspx ★ToolStripItemがオーバーフロー状態になったことを知る ToolStripItemがオーバーフロー状態になったことを知るためのイベ ントは存在しません。しかし、MSDNの「方法 : Windows フォームの ToolStrip オーバーフローを管理する」によると、ToolStripの LayoutCompletedイベントが発生した時に、ToolStripItem.Placement プロパティの値を調べて、ToolStripItemがオーバーフロー状態か調 べることができるということです。 実際のコードは、例えば、次のようになりそうです。ここでは、 toolStripButton1のオーバーフロー状態を監視しています。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Private toolStripButton1Placement As ToolStripItemPlacement = _ ToolStripItemPlacement.None 'toolStrip1のLayoutCompletedイベントハンドラ Private Sub toolStrip1_LayoutCompleted( _ ByVal sender As Object, ByVal e As EventArgs) _ Handles ToolStrip1.LayoutCompleted If ToolStripButton1.Placement <> toolStripButton1Placement Then If ToolStripButton1.Placement = ToolStripItemPlacement.Overflow Then Console.WriteLine( _ "toolStripButton1がオーバーフロー状態になりました") Else If ToolStripButton1.Placement = ToolStripItemPlacement.Main Then Console.WriteLine( _ "toolStripButton1がオーバーフロー状態ではなくなりました") End If End If toolStripButton1Placement = ToolStripButton1.Placement Console.WriteLine(DateTime.Now) End If End Sub ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ private ToolStripItemPlacement toolStripButton1Placement = ToolStripItemPlacement.None; //toolStrip1のLayoutCompletedイベントハンドラ private void toolStrip1_LayoutCompleted(object sender, EventArgs e) { if (toolStripButton1.Placement != toolStripButton1Placement) { if (toolStripButton1.Placement == ToolStripItemPlacement.Overflow) { Console.WriteLine( "toolStripButton1がオーバーフロー状態になりました"); } else if (toolStripButton1.Placement == ToolStripItemPlacement.Main) { Console.WriteLine( "toolStripButton1がオーバーフロー状態ではなくなりました"); } toolStripButton1Placement = toolStripButton1.Placement; Console.WriteLine(DateTime.Now); } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 実際に試してみると分かりますが、toolStripButton1がすでにオーバー フロー状態となっていても、toolStrip1の幅を変えた時に、「オーバー フロー状態になりました」と「オーバーフロー状態ではなくなりまし た」が連続して表示されることがあります。 補足:ToolStripのオーバーフローボタンの実体は、 ToolStripOverflowButtonというToolStripItemであり、ToolStrip. OverflowButtonプロパティで取得することができます。よって、 DropDownItemsプロパティで現在オーバーフロー状態となっているす べてのアイテムを取得できそうですが、実際にはできません。しかし、 HasDropDownItemsプロパティは使えるようです。 ★ToolStripの幅に応じてToolStripItemのDisplayStyleを変更する MSDNの「ToolStrip サンプル」には、「DynamicOverflowForm」とい うサンプルが用意されています。これは、ToolStripの幅が狭くなっ てToolStripItemが表示しきれなくなった時に、ToolStripItemの DisplayStyleプロパティを変更してその幅を縮めることによって、 ToolStripItemがオーバーフローとなることをできるだけ防ぐという ものです。はじめはすべてのToolStripItemのDisplayStyleが ImageAndTextとなっていますが、ToolStripの幅を狭めていくと、 ToolStripItemのDisplayStyleがText、Imageと変化していきます。 なかなか面白いサンプルですので、興味のある方は試してみてくださ い。 [URL]ToolStrip サンプル http://msdn2.microsoft.com/ja-JP/library/ms181005.aspx =============================== ■ここで示したコードの多くはまずC#で書き、それを「C# to VB.NET Translator」でVB.NETのコードに変換し、修正を加えたものです。 [URL][URL]C# to VB.NET Translator http://authors.aspalliance.com/aldotnet/examples/translate.aspx ■このマガジンの購読、購読中止、バックナンバー、説明に関しては  次のページをご覧ください。  http://www.mag2.com/m/0000104516.htm ■発行人・編集人:どぼん!  (Microsoft MVP for Visual Basic, Oct 2005-Oct 2006)  http://dobon.net  dobon_info@yahoo.co.jp ■ご質問等はメールではなく、掲示板へお願いいたします。  http://dobon.net/vb/bbs.html ■上記メールアドレスへのメールは確実に読まれる保障はありません  (スパム、ウィルス対策です)。メールは下記URLのフォームメール  から送信してください。  http://dobon.net/mail.html Copyright (c) 2003 - 2006 DOBON! All rights reserved. ===============================