今回も前回に引き続き、ToolStripに関するTipsを紹介します。2.0の新機能ですので、残念ながら1.0、1.1では使用できません。注意この記事の最新版は「ToolStripに任意のコントロールを配置する」で公開しています。ToolStrip(MenuStrip、ContextMenuStrip、StatusStripなどToolStripから派生したコントロールを含む)に配置できるコントロールは、ToolStripItemクラスから派生したコントロールのみです。2.0では、ToolStripItemクラスから派生したコントロールとして、以下のようなものが用意されています。ツールバーの普通のボタン。画像とテキストが表示できる。ToolStripで使用される。押すとドロップダウンリストが表示されるボタン。Exploreで言えば、「表示」ボタンのような感じ。ToolStrip、StatusStripで使用される。ToolStripDropDownButtonと似ているが、こちらはボタンとドロップダウンボタンが分かれている。Exploreで言えば、「戻る」や「進む」ボタンのような感じ。ToolStrip、StatusStripで使用される。テキストや画像を表示する。コメントやタイトルとして使う。ToolStrip、StatusStripで使用される。グループ分けするセパレータ。ToolStrip、MenuStrip、ContextMenuStripで使用される。メニューで使われる項目。MenuStrip、ContextMenuStripで使用される。StatusStripで使われるパネル。テキストや画像を表示できる。ToolStripで使用される。コンボボックスを表示する。ToolStrip、MenuStrip、ContextMenuStripで使用される。テキストボックスを表示する。ToolStrip、MenuStrip、ContextMenuStripで使用される。ProgressBarを表示する。ToolStrip、StatusStripで使用される。注意:「主に...で使用される。Studioのデザイナを使って配置することができるToolStripの種類を示しています。デザイナを使わずに、コードでToolStripに追加する場合は、その限りではありません。このように、以前のToolBarとは違い、ToolStripには多くのコントロールをのせることができます。これだけでも十分かもしれませんが、さらに、任意のコントロールをToolStripにのせるための方法が用意されています。それが、ToolStripControlHostクラスです。ここではToolStripControlHostを使用した例として、NumericUpDownコントロールをToolStripにのせる方法を説明します。次のようなクラスを作成します。あまりに簡単ですが、これだけで十分です。}}これを実際にToolStripにのせるには、次のようにします(フォームクラスに書かれてるものとします)。普通のToolStripItemをToolStripにのせる場合と同じです。toolStrip1.Items.Add(toolStripNumeric1);}NumericUpDownコントロールをToolStripにのせることはできましたが、NumericUpDownコントロールにアクセスするにはどのようにすればよいのでしょうか?例えば、現在の値(Valueプロパティ)を取得するには、どうしたらいいのでしょうか?ToolStripControlHostがホストしているコントロールは、Controlプロパティで取得できるため、次のようなコードで、Valueプロパティの値を取得できます。1Console.WriteLine(((NumericUpDown)toolStripNumeric1.Control).Value);このように、たったこれだけのコードでも十分ですが、ToolStripNumericUpDownクラスをもう少し改良すると、さらに使いやすくなります。ホストしているNumericUpDownをプロパティで公開します。使うメソッドやプロパティもToolStripNumericUpDownクラスで公開します。ここでは、NumericUpDownの値を設定、取得するためのValueプロパティを作成します。ToolStripNumericUpDownクラス内でNumericUpDownのイベントを処理する必要があれば、OnSubscribeControlEventsとOnUnsubscribeControlEventsメソッドを使用すると、効率的です。ここでは、NumericUpDownの値が変化した時に発生するValueChangedイベントを追加することにします。以上のように改良したToolStripNumericUpDownクラスは、次のようになります。}}改良したToolStripNumericUpDownクラスの使い方は、次のようになります(フォームクラスに書かれてるものとします)。Studioのデザイナで表示する」で公開しています。Studioのデザイナでは、ToolStripの端に新しいToolStripItemを追加するためのボタンが表示され、これを使って簡単にToolStripItemを追加することができます。Studioのデザイナに表示されないため、コードでToolStripに配置しなければなりません。Studioのデザイナで表示させる方法を紹介します。自作のToolStripItemをデザイナで表示してToolStripに追加できるようにするには、ToolStripItemDesignerAvailability属性を使用します。次のようなToolStripNumericUpDownを定義すれば、フォームデザイナのToolStripとStatusStripでこのToolStripNumericUpDownを追加することができるようになります。}}さらに、デザイナでToolStripItemを追加する時のメニューで左側に表示される画像を変更するには、ToolboxBitmap属性を使います。(画像が指定されていないと、歯車の画像が表示されます。)次の例では、「OpenFolder.bmp」という画像が「埋め込まれたリソース」としてアセンブリに埋め込まれている時に、これをToolStripNumericUpDownの画像としています。画像は、16X16の大きさである必要があります。}}これとは別に、ToolboxItem属性を使って画像を指定することもできます。この方法では、画像のほかに、表示名や説明を変更することもできます。"数字を入力できます。"数字を入力できます。注意この記事の最新版は「ToolStripItemの位置をユーザーが変えられるようにする」で公開しています。ToolStripのAllowDropプロパティをFalseとして、AllowItemReorderプロパティをTrueとすると、ユーザーがAltキーを押しながらToolStripItemをドラッグすることにより、その位置を変更することができます。AllowDropプロパティとAllowItemReorderプロパティの両方をTrueとすることはできません。AllowItemReorderプロパティをTrueとしても移動できないToolStripItemも多く存在します。ToolStripComboBox、ToolStripProgressBar、ToolStripTextBoxなど、ToolStripControlHostを継承したToolStripItemは移動できないようです。ToolStripItemの位置を保存、復元する方法は、前々号で説明したとおり、ToolStripManager.SaveSettings、LoadSettingsメソッドを使います。サンプル」(CustomizeToolStripプロジェクト)にあります。注意この記事の最新版は「あるToolStripItemの右側に指定したToolStripItemが常にあるようにする」で公開しています。ToolStripにToolStripComboBoxが配置されており、その説明のためにすぐ左側にToolStripLabelを配置した場合、常にToolStripLabelがToolStripComboBoxの左隣にないと意味不明になってしまいます。ToolStripのAllowItemReorderをTrueとしてユーザーがToolStripItemの位置を自由に変更できる時は、そうなってしまう可能性が十分あります。これを防ぐために、あるToolStripItemの右側に指定したToolStripItemが常にあるようにする方法を考えてみました。いろいろな方法が考えられますが、ここではToolStripItemのLocationChangedイベントで処理することにします。下に示す例では、ToolStripにToolStripLabel(toolStripLabel1)とToolStripComboBox(toolStripComboBox1)が配置されているとき、toolStripLabel1の右隣に常にtoolStripComboBox1があるようしています。}}この方法は、ユーザーが移動することのできないToolStripControlHostを継承したToolStripItemをユーザーが移動できるようにする方法としても使えるかもしれません。最後に、ここで述べるほどでは無いかもしれないつまらないTipをいくつか紹介します。注意この記事の最新版は「ToolStripItemを表示あるいは非表示にする」で公開しています。これは、Visibleプロパティを使えばよさそうですが、そう単純ではありません。ToolStripItemにはこれと同じような目的に使用する、Availableプロパティというものが存在するのです。両者の違いについてMSDNでは、次のように書かれています(そのまま引用します)。プロパティとは異なります。その親を表示するかどうかを示します。プロパティつまり、両者は値の設定に関しては全く同じであり、取得に関してのみ異なるということのようです。実際、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にしておいた方が良いでしょう。注意この記事の最新版は「右端に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に収まらなくなったら、表示されなくなります。メニューに送信できるかどうかを示す値を取得または設定します。「オーバーフローメニューに送信」という意味が、オーバーフローメニューに移動するということであれば、この説明が正しいのか、疑問です。CanOverflowプロパティがFalseの時、OverflowプロパティがAlwaysのToolStripItemはToolStripに全く表示されません(ToolStrip.LayoutStyleプロパティがTableまたはFlowの時は、表示されます)。これは多分、OverflowがAlwaysのToolStripItemがオーバーフローメニューに移動したが、オーバーフローボタンが表示されなくなったため見えなくなったものと考えられます。CanOverflowプロパティはオーバーフローボタンを表示するかどうかを指定するものと解釈した方が良さそうです。(説明が正しく、動作が間違っている可能性もありますが。注意この記事の最新版は「ToolStripItemがオーバーフロー状態になったことを知る」で公開しています。ToolStripItemがオーバーフロー状態になったことを知るためのイベントは存在しません。オーバーフローを管理する」によると、ToolStripのLayoutCompletedイベントが発生した時に、ToolStripItem.Placementプロパティの値を調べて、ToolStripItemがオーバーフロー状態か調べることができるということです。実際のコードは、例えば、次のようになりそうです。ここでは、toolStripButton1のオーバーフロー状態を監視しています。}}実際に試してみると分かりますが、toolStripButton1がすでにオーバーフロー状態となっていても、toolStrip1の幅を変えた時に、「オーバーフロー状態になりました」と「オーバーフロー状態ではなくなりました」が連続して表示されることがあります。補足:ToolStripのオーバーフローボタンの実体は、ToolStripOverflowButtonというToolStripItemであり、ToolStrip.OverflowButtonプロパティで取得することができます。よって、DropDownItemsプロパティで現在オーバーフロー状態となっているすべてのアイテムを取得できそうですが、実際にはできません。HasDropDownItemsプロパティは使えるようです。注意この記事の最新版は「ToolStripの幅に応じてToolStripItemのDisplayStyleを変更する」で公開しています。サンプル」には、「DynamicOverflowForm」というサンプルが用意されています。これは、ToolStripの幅が狭くなってToolStripItemが表示しきれなくなった時に、ToolStripItemのDisplayStyleプロパティを変更してその幅を縮めることによって、ToolStripItemがオーバーフローとなることをできるだけ防ぐというものです。はじめはすべてのToolStripItemのDisplayStyleがImageAndTextとなっていますが、ToolStripの幅を狭めていくと、ToolStripItemのDisplayStyleがText、Imageと変化していきます。面白いサンプルですので、一度お試しください。