- 追加された行はこの色です。
- 削除された行はこの色です。
#title(.NETプログラミング研究 第67号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第67号 [#a75560e4]
**.NET Tips [#cc475534]
今回も前回に引き続き、ToolStripとToolStripContainerに関するTipsを紹介します。
**ToolStripやToolStripContainerの外観を変更する [#ac8585b8]
#column(注意){{
この記事の最新版は「[[ToolStripやToolStripContainerの外観を変更する>http://dobon.net/vb/dotnet/control/tsrenderer.html]]」で公開しています。
この記事の最新版は「[[ToolStripやToolStripContainerの外観を変更する>https://dobon.net/vb/dotnet/control/tsrenderer.html]]」で公開しています。
}}
ToolStripやToolStripContainer(以下まとめてToolStripとする)の外観を変更するための方法として、RenderModeプロパティとRendererプロパティが用意されています。
***RenderModeプロパティ [#gebb0541]
まずは、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の外観が変更されることでしょう。
#code(vbnet){{
ToolStripManager.RenderMode = ToolStripManagerRenderMode.System
}}
#code(csharp){{
ToolStripManager.RenderMode = ToolStripManagerRenderMode.System;
}}
-[[ToolStripManager.RenderMode プロパティ>http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.toolstripmanager.rendermode.aspx]]
***Rendererプロパティ [#y0918f4b]
もっと細かくToolStripの外観をカスタマイズするには、Rendererプロパティを設定することになります。そのためには、ToolStripRendererクラスを継承したクラスを作成して、どのように描画するかをすべて指定しなければなりません(具体的な方法は、後述します)。
ただ、これはあまりに面倒です。そこで、.NET Framework 2.0では、ToolStripRendererを継承した2つのクラス、ToolStripSystemRendererとToolStripProfessionalRendererクラスがあらかじめ用意されています。
実は、RenderModeプロパティをSystemにするとRendererにToolStripSystemRendererを使い、ProfessionalにするとToolStripProfessionalRendererを使うということなのです。つまり、先ほどのToolStripManager.RenderModeをSystemにするというコードは、次のようなコードであっても、外観がどうなるかという結果に関しては、全く同じになります。
#code(vbnet){{
ToolStripManager.Renderer = New ToolStripSystemRenderer()
}}
#code(csharp){{
ToolStripManager.Renderer = new ToolStripSystemRenderer();
}}
-[[ToolStripManager.Renderer プロパティ>http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.toolstripmanager.renderer.aspx]]
***ProfessionalColorTableクラス [#je98b55d]
ToolStripProfessionalRendererクラスには、ToolStripの外観の色を変更するための、簡単で面白い方法が用意されています。RenderModeがProfessionalの時は、Office XPのような、グラデーションのかかったカッコいい見た目になりますが、どのような色でグラデーションをかけるかを簡単に変更することができるのです。
そのためには、ProfessionalColorTableクラスを継承したクラスを作成し、ここでグラデーションのかけ方を指定し、このオブジェクトを指定して、ToolStripProfessionalRendererオブジェクトを作成します。
まずは例をご覧ください。はじめにProfessionalColorTableクラスを継承したCustomProfessionalRendererクラスを作成します。ここでは、ToolStripとToolStripPanelの色だけを変更しています。
#code(vbnet){{
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
}}
#code(csharp){{
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の外観を変更するには、次のようにします。
#code(vbnet){{
'アプリケーション全体にカスタムのプロフェッショナルレンダラを適用する
ToolStripManager.Renderer = _
New ToolStripProfessionalRenderer( _
New CustomProfessionalRenderer())
}}
#code(csharp){{
//アプリケーション全体にカスタムのプロフェッショナルレンダラを適用する
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は全く無視され、どのようにすれば有効になるのか分かりませんでした。
-[[ProfessionalColorTable クラス>http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.professionalcolortable.aspx]]
-[[ProfessionalColors メンバ>http://msdn2.microsoft.com/ja-JP/library/system.windows.forms.professionalcolors.aspx]]
-[[方法 : ToolStrip アプリケーションの色をカスタマイズする>http://msdn2.microsoft.com/ja-jp/library/ms229724.aspx]]
-[[方法 : 実行時に ToolStrip レンダラを設定する>http://msdn2.microsoft.com/ja-JP/library/ms229637.aspx]]
***カスタムToolStripRenderer [#o912fe66]
さらに細かくToolStripの外観を指定したい場合は、ToolStripRendererクラスの派生クラスを独自に作成し、ToolStripをどのように描画するかを指定します。
ToolStripRendererクラスは抽象クラスですので、必ず派生クラスを作成する必要があります。抽象メンバはありませんので、必ずオーバーライドしなければならないメンバはありませんが、そのままでは画像やテキストが表示されるだけで、使い物になりません。もしToolStripRendererクラスを直接継承するのであれば、多くのメソッドをオーバーライドする必要があるでしょう。
-[[ToolStripRenderer クラス>http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.toolstriprenderer.aspx]]
もしToolStripSystemRendererやToolStripProfessionalRendererを基にして、その一部分の描画を変更するだけであれば、これらのクラスを継承して、適当なメソッドをオーバーライドするだけでよいので、簡単です。
以下に、ToolStripProfessionalRendererを継承して、OnRenderToolStripBackgroundとOnRenderButtonBackgroundをオーバーライドすることにより、ToolStripの背景とToolStripButtonの背景を独自に描画する例を示します。
#code(vbnet){{
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
}}
#code(csharp){{
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();
}
}
}}
-[[方法 : プロフェッショナル スタイルの ToolStrip コントロールを作成する>http://msdn2.microsoft.com/ja-JP/library/ms229725.aspx]]
-[[方法 : カスタムの ToolStripRenderer を実装する>http://msdn2.microsoft.com/ja-jp/library/ms229720.aspx]]
実はこのようなカスタムのToolStripRendererクラスを作成しなくても、ToolStripRendererクラスのイベントを処理することにより、同じことができます。
#code(vbnet){{
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
}}
#code(csharp){{
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の角を四角くする [#o2bd4e2a]
ToolStripProfessionalRendererを使うと、デフォルトではToolStripの角が丸くなりますが、ToolStripProfessionalRenderer.RenderToolStripBackgroundプロパティをFalseにすることにより、角を四角くすることができます。ただそれだけです...。
#code(vbnet){{
Dim proRenderer As New ToolStripProfessionalRenderer()
proRenderer.RoundedEdges = False
ToolStripManager.Renderer = proRenderer
}}
#code(csharp){{
ToolStripProfessionalRenderer proRenderer =
new ToolStripProfessionalRenderer();
proRenderer.RoundedEdges = false;
ToolStripManager.Renderer = proRenderer;
}}
***ToolStripのVisualスタイルを無効にする [#t8d0bd40]
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の値を見て描画法を変更するようにします。
#code(vbnet){{
'Visualスタイルを無効にする
ToolStripManager.VisualStylesEnabled = False
}}
#code(csharp){{
//Visualスタイルを無効にする
ToolStripManager.VisualStylesEnabled = false;
}}
しつこいようですが、次回もToolStripに関するTipを紹介する予定です。
**コメント [#i7e6122b]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2006-03-23 (木) 06:00:00,DOBON!,2010-03-23 (火) 02:26:13,DOBON!)