.NETプログラミング研究 第67号

.NET Tips

今回も前回に引き続き、ToolStripとToolStripContainerに関するTipsを紹介します。

ToolStripやToolStripContainerの外観を変更する

注意

この記事の最新版は「ToolStripやToolStripContainerの外観を変更する」で公開しています。

ToolStripやToolStripContainer(以下まとめてToolStripとする)の外観を変更するための方法として、RenderModeプロパティとRendererプロパティが用意されています。

RenderModeプロパティ

まずは、VS2005のデザイナを使って、手軽に外観を変更させてみましょう。

ToolStripやToolStripContentPanel、ToolStripPanelコントロールには、RenderModeプロパティが用意されており、デザイナでこの値を変更することができます。RenderModeプロパティをSystemに変更すると、MS Office XPのような外観だったものが、エクスプローラのような地味な外観に変化するのが分かるでしょう。このように、RenderModeプロパティをSystemにするとエクスプローラのような外観になり、ProfessionalにするとMS Office XPのような外観になります。

RenderModeプロパティはデフォルトでManagerRenderModeになっていますが、これは何でしょうか?実は、RenderModeプロパティがManagerRenderModeの時は、静的プロパティであるToolStripManager.RenderModeとRendererプロパティが使われます。つまり、RenderModeプロパティがManagerRenderModeとなっているすべてのToolStrip(及び、ToolStripContentPanel、ToolStripPanel)には、ToolStripManager.RenderModeとRendererプロパティの設定が使われます。逆に言えば、、ToolStripManager.RenderModeあるいはRendererの値を変更することにより、アプリケーション内のすべてのToolStripの外観を一度に変更することができるということです。

試しに、次のようなコードを実行してみてください。RenderModeがManagerRenderModeのすべてのToolStrip、ToolStripContentPanel、ToolStripPanelの外観が変更されることでしょう。

  1
ToolStripManager.RenderMode = ToolStripManagerRenderMode.System
  1
ToolStripManager.RenderMode = ToolStripManagerRenderMode.System;

Rendererプロパティ

もっと細かくToolStripの外観をカスタマイズするには、Rendererプロパティを設定することになります。そのためには、ToolStripRendererクラスを継承したクラスを作成して、どのように描画するかをすべて指定しなければなりません(具体的な方法は、後述します)。

ただ、これはあまりに面倒です。そこで、.NET Framework 2.0では、ToolStripRendererを継承した2つのクラス、ToolStripSystemRendererとToolStripProfessionalRendererクラスがあらかじめ用意されています。

実は、RenderModeプロパティをSystemにするとRendererにToolStripSystemRendererを使い、ProfessionalにするとToolStripProfessionalRendererを使うということなのです。つまり、先ほどのToolStripManager.RenderModeをSystemにするというコードは、次のようなコードであっても、外観がどうなるかという結果に関しては、全く同じになります。

  1
ToolStripManager.Renderer = New ToolStripSystemRenderer()
  1
ToolStripManager.Renderer = new ToolStripSystemRenderer();

ProfessionalColorTableクラス

ToolStripProfessionalRendererクラスには、ToolStripの外観の色を変更するための、簡単で面白い方法が用意されています。RenderModeがProfessionalの時は、Office XPのような、グラデーションのかかったカッコいい見た目になりますが、どのような色でグラデーションをかけるかを簡単に変更することができるのです。

そのためには、ProfessionalColorTableクラスを継承したクラスを作成し、ここでグラデーションのかけ方を指定し、このオブジェクトを指定して、ToolStripProfessionalRendererオブジェクトを作成します。

まずは例をご覧ください。はじめにProfessionalColorTableクラスを継承したCustomProfessionalRendererクラスを作成します。ここでは、ToolStripとToolStripPanelの色だけを変更しています。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
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
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
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の外観を変更するには、次のようにします。

  1
  2
  3
  4
'アプリケーション全体にカスタムのプロフェッショナルレンダラを適用する
ToolStripManager.Renderer = _
    New ToolStripProfessionalRenderer( _
    New CustomProfessionalRenderer())
  1
  2
  3
  4
//アプリケーション全体にカスタムのプロフェッショナルレンダラを適用する
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は全く無視され、どのようにすれば有効になるのか分かりませんでした。

カスタムToolStripRenderer

さらに細かくToolStripの外観を指定したい場合は、ToolStripRendererクラスの派生クラスを独自に作成し、ToolStripをどのように描画するかを指定します。

ToolStripRendererクラスは抽象クラスですので、必ず派生クラスを作成する必要があります。抽象メンバはありませんので、必ずオーバーライドしなければならないメンバはありませんが、そのままでは画像やテキストが表示されるだけで、使い物になりません。もしToolStripRendererクラスを直接継承するのであれば、多くのメソッドをオーバーライドする必要があるでしょう。

もしToolStripSystemRendererやToolStripProfessionalRendererを基にして、その一部分の描画を変更するだけであれば、これらのクラスを継承して、適当なメソッドをオーバーライドするだけでよいので、簡単です。

以下に、ToolStripProfessionalRendererを継承して、OnRenderToolStripBackgroundとOnRenderButtonBackgroundをオーバーライドすることにより、ToolStripの背景とToolStripButtonの背景を独自に描画する例を示します。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
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
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
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();
    }
}

実はこのようなカスタムのToolStripRendererクラスを作成しなくても、ToolStripRendererクラスのイベントを処理することにより、同じことができます。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
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
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
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を使うと、デフォルトではToolStripの角が丸くなりますが、ToolStripProfessionalRenderer.RenderToolStripBackgroundプロパティをFalseにすることにより、角を四角くすることができます。ただそれだけです...。

  1
  2
  3
Dim proRenderer As New ToolStripProfessionalRenderer()
proRenderer.RoundedEdges = False
ToolStripManager.Renderer = proRenderer
  1
  2
  3
  4
ToolStripProfessionalRenderer proRenderer =
    new ToolStripProfessionalRenderer();
proRenderer.RoundedEdges = false;
ToolStripManager.Renderer = proRenderer;

ToolStripのVisualスタイルを無効にする

ToolStripManager.VisualStylesEnabledメソッドをFalseとすることにより、ToolStripのVisualスタイル(Windows XPで使用されている外観のスタイル)を無効にできます。つまり、VisualStylesEnabledメソッドをFalseとすると、ToolStripの見た目はWindows XPより古いWindowsで実行したExplore(レンダラがToolStripSystemRendererの時)やMS Office XP(レンダラがToolStripProfessionalRendererの時)のようになります。

今まで紹介してきたように、ProfessionalColorTableクラスや、ToolStripRendererの派生クラスを使ってToolStripの外観を変更した場合は、これらにより描画法が変更された箇所はVisualStylesEnabledメソッドの影響を受けないようです。逆に、VisualStylesEnabledの値によりカスタムToolStripRendererの描画法を変更したい場合は、ToolStripManager.VisualStylesEnabledの値を見て描画法を変更するようにします。

  1
  2
'Visualスタイルを無効にする
ToolStripManager.VisualStylesEnabled = False
  1
  2
//Visualスタイルを無効にする
ToolStripManager.VisualStylesEnabled = false;

しつこいようですが、次回もToolStripに関するTipを紹介する予定です。

コメント



ページ情報
  • カテゴリ : .NET
  • 作成日 : 2006-03-23 (木) 06:00:00
  • 作成者 : DOBON!
  • 最終編集日 : 2010-03-23 (火) 02:26:13
  • 最終編集者 : DOBON!
[ トップ ]   [ 編集 | 凍結 | 差分 | バックアップ | 添付 | 複製 | 名前変更 | リロード ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]