注意:ここで紹介している方法は、.NET Framework 2.0以降でのみ使用できます。
ToolStripやToolStripContainer(以下まとめてToolStripとする)の外観を変更するための方法として、RenderModeプロパティとRendererプロパティが用意されています。
まずは、Visual Studioのフォームデザイナを使って、手軽に外観を変更させてみましょう。
ToolStripやToolStripContentPanel、ToolStripPanelコントロールには、RenderModeプロパティが用意されており、フォームデザイナでこの値を変更することができます。
RenderModeプロパティの値はデフォルトでManagerRenderModeですが、SystemかProfessionalに変更することができます(.NET Framework 4.5現在)。RenderModeプロパティをSystemに変更すると、地味な(システムカラーとフラットなvisualスタイルを使用した)外観になります。Professionalに変更すると、Microsoft Officeのような外観になります。
以下の画像は、RenderModeプロパティをSystemにした時のものです。
RenderModeプロパティはデフォルトでManagerRenderModeですが、これは何でしょうか?実は、RenderModeプロパティがManagerRenderModeの時は、静的プロパティであるToolStripManager.RenderModeとToolStripManager.Rendererプロパティが使われます。つまり、RenderModeプロパティがManagerRenderModeとなっているすべてのToolStrip(及び、ToolStripContentPanel、ToolStripPanel)には、ToolStripManager.RenderModeとRendererプロパティの設定が使われます。逆に言えば、、ToolStripManager.RenderModeあるいはRendererの値を変更することにより、アプリケーション内のすべてのToolStripの外観を一度に変更することができるということです。
試しに、次のようなコードを実行してみてください。RenderModeがManagerRenderModeのすべてのToolStrip、ToolStripContentPanel、ToolStripPanelの外観がSystemに変更されることでしょう。
ToolStripManager.RenderMode = ToolStripManagerRenderMode.System
ToolStripManager.RenderMode = ToolStripManagerRenderMode.System;
もっと細かくToolStripの外観をカスタマイズするには、Rendererプロパティを設定することになります。そのためには、ToolStripRendererクラスを継承したクラスを作成して、どのように描画するかをすべて指定しなければなりません(具体的な方法は、後述します)。
ただ、これはあまりに面倒です。そこで、.NET Framework 2.0では、ToolStripRendererを継承した2つのクラス、ToolStripSystemRendererとToolStripProfessionalRendererクラスがあらかじめ用意されています。
実は、RenderModeプロパティをSystemにするとRendererにToolStripSystemRendererを使い、ProfessionalにするとToolStripProfessionalRendererを使うということなのです。つまり、先ほどのToolStripManager.RenderModeをSystemにするというコードは、次のようなコードであっても、外観がどうなるかという結果に関しては、全く同じになります。
ToolStripManager.Renderer = New ToolStripSystemRenderer()
ToolStripManager.Renderer = new ToolStripSystemRenderer();
ToolStripProfessionalRendererクラスには、ToolStripの外観の色を変更するための、簡単で面白い方法が用意されています。RenderModeがProfessionalの時は、Microsoft Officeのような、グラデーションのかかったカッコいい見た目になりますが、どのような色でグラデーションをかけるかを簡単に変更することができるのです。
そのためには、ProfessionalColorTableクラスを継承したクラスを作成し、ここでグラデーションのかけ方を指定し、このオブジェクトを指定して、ToolStripProfessionalRendererオブジェクトを作成します。
まずは例をご覧ください。はじめにProfessionalColorTableクラスを継承したCustomProfessionalRendererクラスを作成します。ここでは、ToolStripとToolStripPanelの色だけを変更しています。
Public Class CustomProfessionalRenderer Inherits ProfessionalColorTable 'ToolStripのグラデーションの色を指定 Public Overrides ReadOnly Property ToolStripGradientBegin() As Color Get Return Color.WhiteSmoke End Get End Property Public Overrides ReadOnly Property ToolStripGradientMiddle() As Color Get Return Color.LightGray End Get End Property Public Overrides ReadOnly Property ToolStripGradientEnd() As Color Get Return Color.Gray End Get End Property 'ToolStripPanelのグラデーションの色を指定 Public Overrides ReadOnly Property ToolStripPanelGradientBegin() As Color Get Return Color.Gold End Get End Property Public Overrides ReadOnly Property ToolStripPanelGradientEnd() As Color Get Return Color.Ivory End Get End Property End Class
using System.Windows.Forms; using System.Drawing; public class CustomProfessionalRenderer : ProfessionalColorTable { //ToolStripのグラデーションの色を指定 public override Color ToolStripGradientBegin { get { return Color.WhiteSmoke; } } public override Color ToolStripGradientMiddle { get { return Color.LightGray; } } public override Color ToolStripGradientEnd { get { return Color.Gray; } } //ToolStripPanelのグラデーションの色を指定 public override Color ToolStripPanelGradientBegin { get { return Color.Gold; } } public override Color ToolStripPanelGradientEnd { get { return Color.Ivory; } } }
ToolStripGradientBegin、ToolStripGradientMiddle、ToolStripGradientEndプロパティでToolStripにグラデーションの開始色、中間色、終了色を指定し、ToolStripPanelGradientBeginとToolStripPanelGradientEndでToolStripPanelにグラデーションの開始色と終了色を指定します。
このCustomProfessionalRendererを使って実際にToolStripとToolStripPanelの外観を変更するには、次のようにします。
'アプリケーション全体にカスタムのプロフェッショナルレンダラを適用する ToolStripManager.Renderer = _ New ToolStripProfessionalRenderer(New CustomProfessionalRenderer())
//アプリケーション全体にカスタムのプロフェッショナルレンダラを適用する ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomProfessionalRenderer());
上記の例では、見た目が次のように変化します。
個々のToolStripやToolStripPanelのみを変更するのであれば、そのコントロールのRendererにToolStripProfessionalRendererオブジェクトを設定してください。
補足:Rendererにカスタムレンダラを設定すると、RenderModeプロパティは自動的にCustomとなります。
私がProfessionalColorTableを使ってみて気が付いた点を以下に挙げます。
ToolStripGradientMiddleを指定しないと、デフォルトの色が使われるようですので、ToolStripGradientBeginとToolStripGradientEndを変更するならば、ToolStripGradientMiddleも変更しないと、意図した色にならないでしょう。(しかし、ButtonSelectedGradientMiddleやMenuItemPressedGradientMiddleなど、...Middleの他のメソッドは、指定しても無視されました。)
グラデーションの方向に関しては、MSDNに何の説明もありません。そこで私が実際に試して調べた結果を記述しておきます。
ToolStripGradientBegin、ToolStripGradientMiddle、ToolStripGradientEndによるToolStripのグラデーションでは、ToolStripが横長(LayoutStyleがHorizontalStackWithOverflow)の時は、左から右へのグラデーションとなり、ToolStripが縦長(LayoutStyleがVerticalStackWithOverflow)の時は、上から下へのグラデーションとなります。
ToolStripPanelGradientBegin、ToolStripPanelGradientEndによるToolStripPanelのグラデーションでは、左から右へのグラデーションとなります。しかし、必ずしもToolStripPanelの左端がToolStripPanelGradientBeginで指定した色で、右端がToolStripPanelGradientEndで指定した色とはならず、その間の一部分のようにグラデーションがかかります。
MenuStripのMenuStripGradientBegin、MenuStripGradientEndでは、MenuStripが横長の場合に、左から右へのグラデーションとなります。縦長の場合は、グラデーションとならず、MenuStripGradientBeginで指定した一色のみとなるようです。
MenuItemPressedGradientBegin、MenuItemPressedGradientEndなど、MenuItemの場合は、上から下へのグラデーションとなります。(なお、MenuItemPressedGradient...やMenuItemSelectedGradient...は、ToolStripComboBoxの下矢印ボタンにも使用されます。)
OverflowButtonGradientBegin、OverflowButtonGradientEndによるオーバーフローボタンは、MenuStripが横長の場合は上から下、横長の場合は左から右のグラデーションとなります。(なお、ToolStripOverflowButtonの選択時や、押した時の色は、ButtonSelectedGradient...やButtonPressedGradient...が使用されます。)
ToolStripContainerのContentPanelのRendererはグラデーションとならず、ToolStripContentPanelGradientEndで指定した一色となりました。
また、RaftingContainerGradientBeginとRaftingContainerGradientEndは全く無視され、どのようにすれば有効になるのか分かりませんでした。
さらに細かくToolStripの外観を指定したい場合は、ToolStripRendererクラスの派生クラスを独自に作成し、ToolStripをどのように描画するかを指定します。
ToolStripRendererクラスは抽象クラスですので、必ず派生クラスを作成する必要があります。抽象メンバはありませんので、必ずオーバーライドしなければならないメンバはありませんが、そのままでは画像やテキストが表示されるだけで、使い物になりません。もしToolStripRendererクラスを直接継承するのであれば、多くのメソッドをオーバーライドする必要があるでしょう。
もしToolStripSystemRendererやToolStripProfessionalRendererを基にして、その一部分の描画を変更するだけであれば、これらのクラスを継承して、適当なメソッドをオーバーライドするだけでよいので、簡単です。
以下に、ToolStripProfessionalRendererを継承して、OnRenderToolStripBackgroundとOnRenderButtonBackgroundをオーバーライドすることにより、ToolStripの背景とToolStripButtonの背景を独自に描画する例を示します。
Imports System.Windows.Forms Imports System.Drawing Public Class CustomRenderer Inherits ToolStripProfessionalRenderer 'ToolStripの背景を描画 Protected Overrides Sub OnRenderToolStripBackground( _ ByVal e As ToolStripRenderEventArgs) Dim b As New SolidBrush(Color.LightGray) e.Graphics.FillRectangle(b, e.AffectedBounds) b.Dispose() End Sub 'ToolStripButtonの背景を描画 Protected Overrides Sub OnRenderButtonBackground( _ ByVal e As ToolStripItemRenderEventArgs) Dim btn As ToolStripButton = CType(e.Item, ToolStripButton) Dim b As SolidBrush If btn.Pressed Or btn.Checked Then 'ボタンが押されている時 b = New SolidBrush(Color.LightSalmon) Else If btn.Selected Then 'ボタンが選択されている時 b = New SolidBrush(Color.Aquamarine) Else 'ボタンが普通の状態の時 b = New SolidBrush(Color.Silver) End If End If 'ボタンの背景を描画する e.Graphics.FillRectangle(b, btn.ContentRectangle) b.Dispose() End Sub End Class
using System.Windows.Forms; using System.Drawing; public class CustomRenderer : ToolStripProfessionalRenderer { //ToolStripの背景を描画 protected override void OnRenderToolStripBackground( ToolStripRenderEventArgs e) { SolidBrush b = new SolidBrush(Color.LightGray); e.Graphics.FillRectangle(b, e.AffectedBounds); b.Dispose(); } //ToolStripButtonの背景を描画 protected override void OnRenderButtonBackground( ToolStripItemRenderEventArgs e) { ToolStripButton btn = (ToolStripButton)e.Item; SolidBrush b; if (btn.Pressed || btn.Checked) { //ボタンが押されている時 b = new SolidBrush(Color.LightSalmon); } else if (btn.Selected) { //ボタンが選択されている時 b = new SolidBrush(Color.Aquamarine); } else { //ボタンが普通の状態の時 b = new SolidBrush(Color.Silver); } //ボタンの背景を描画する e.Graphics.FillRectangle(b, btn.ContentRectangle); b.Dispose(); } }
使い方はやはり同じように、たとえば、
ToolStripManager.Renderer = New CustomRenderer()
のようにします。
実はこのようなカスタムのToolStripRendererクラスを作成しなくても、ToolStripRendererクラスのイベント(ToolStripRenderer.RenderToolStripBackgroundイベント)を処理することにより、同じことができます。
Protected Overrides Sub OnLoad(ByVal e As EventArgs) MyBase.OnLoad(e) Dim proRenderer As New ToolStripProfessionalRenderer() AddHandler proRenderer.RenderToolStripBackground, _ AddressOf proRenderer_RenderToolStripBackground ToolStripManager.Renderer = proRenderer End Sub Private Sub proRenderer_RenderToolStripBackground( _ ByVal sender As Object, ByVal e As ToolStripRenderEventArgs) Dim b As New SolidBrush(Color.LightGray) e.Graphics.FillRectangle(b, e.AffectedBounds) b.Dispose() End Sub
protected override void OnLoad(EventArgs e) { base.OnLoad(e); ToolStripProfessionalRenderer proRenderer = new ToolStripProfessionalRenderer(); proRenderer.RenderToolStripBackground += new ToolStripRenderEventHandler(proRenderer_RenderToolStripBackground); ToolStripManager.Renderer = proRenderer; } private void proRenderer_RenderToolStripBackground( object sender, ToolStripRenderEventArgs e) { SolidBrush b = new SolidBrush(Color.LightGray); e.Graphics.FillRectangle(b, e.AffectedBounds); b.Dispose(); }
ToolStripProfessionalRendererを使うと、デフォルトではToolStripの角が丸くなりますが、ToolStripProfessionalRenderer.RoundedEdgesプロパティをFalseにすることにより、角を四角くすることができます。ただそれだけです...。
Dim proRenderer As New ToolStripProfessionalRenderer() proRenderer.RoundedEdges = False ToolStripManager.Renderer = proRenderer
ToolStripProfessionalRenderer proRenderer = new ToolStripProfessionalRenderer(); proRenderer.RoundedEdges = false; ToolStripManager.Renderer = proRenderer;
ToolStripManager.VisualStylesEnabledメソッドをFalseとすることにより、ToolStripのVisualスタイルを無効にできます。
ただし、カスタムToolStripRendererで描画している場所(今まで紹介してきたように、ProfessionalColorTableクラスや、ToolStripRendererの派生クラスを使ってToolStripの外観を変更した場所)は、VisualStylesEnabledメソッドの影響を受けません。つまり、カスタムToolStripRendererでもVisualStylesEnabledの値が使えるようにするには、VisualStylesEnabledの値を見て自分で描画法を変更するようにする必要があります。
VisualStylesEnabledをFalseにするコードは、以下のようになります。
'Visualスタイルを無効にする ToolStripManager.VisualStylesEnabled = False
//Visualスタイルを無効にする ToolStripManager.VisualStylesEnabled = false;
(この記事は、「.NETプログラミング研究」で紹介したものを基にしています。)