【C#/WinForms】メニューにハイコントラストテーマを適用する方法

C#
この記事は約23分で読めます。

Windows Form アプリケーションのメニューバーやツールバーにハイコントラストテーマを適用する方法です。.NET8 を対象にしています。

適用イメージ

ハイコントラストテーマは黒、白、オレンジ、水色のみの配色になります。自作テキストエディタ(TZEditor)に適用してみました。タイトルバーは独自に実装しています。

ハイコントラストテーマ

ハイコントラストカラーテーブル

VS Code のハイコントラスト風カラーテーブルです。

using System.Windows.Forms;
using System.Drawing;

namespace Test {
    public class HighContrastColorTable : ProfessionalColorTable {

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public HighContrastColorTable() {
            this.UseSystemColors = false;
        }

        /// <summary>
        /// ボタンがオンの場合に使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color ButtonCheckedGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンがオンの場合に使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color ButtonCheckedGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンがオンの場合に使用するグラデーションの中間色を取得します。
        /// <summary>
        public override Color ButtonCheckedGradientMiddle => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンがオンの場合に使用する純色を取得します。
        /// <summary>
        public override Color ButtonCheckedHighlight => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ButtonCheckedHighlight で使用する境界線の色を取得します。
        /// <summary>
        public override Color ButtonCheckedHighlightBorder => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ButtonPressedGradientBegin、 ButtonPressedGradientMiddle、および ButtonPressedGradientEnd の各色で使用する境界線の色を取得します。
        /// <summary>
        public override Color ButtonPressedBorder => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンが押されている場合に使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color ButtonPressedGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンが押されている場合に使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color ButtonPressedGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンが押されている場合に使用するグラデーションの中間色を取得します。
        /// <summary>
        public override Color ButtonPressedGradientMiddle => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンが押されている場合に使用する純色を取得します。
        /// <summary>
        public override Color ButtonPressedHighlight => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ButtonPressedHighlight で使用する境界線の色を取得します。
        /// <summary>
        public override Color ButtonPressedHighlightBorder => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ButtonSelectedGradientBegin、 ButtonSelectedGradientMiddle、および ButtonSelectedGradientEnd の各色で使用する境界線の色を取得します。
        /// <summary>
        public override Color ButtonSelectedBorder => Color.FromArgb(255, 243, 133, 24);
        /// <summary>
        /// ボタンがオンの場合に使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color ButtonSelectedGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンがオンの場合に使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color ButtonSelectedGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンがオンの場合に使用するグラデーションの中間色を取得します。
        /// <summary>
        public override Color ButtonSelectedGradientMiddle => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ボタンがオンの場合に使用する純色を取得します。
        /// <summary>
        public override Color ButtonSelectedHighlight => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ButtonSelectedHighlight で使用する境界線の色を取得します。
        /// <summary>
        public override Color ButtonSelectedHighlightBorder => Color.FromArgb(255, 243, 133, 24);
        /// <summary>
        /// チェック ボタンがオンで、グラデーションが使用される場合に使用する純色を取得します。
        /// <summary>
        public override Color CheckBackground => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// チェック ボタンがオンで、グラデーションが使用されるときに使用する純色を取得します。
        /// <summary>
        public override Color CheckPressedBackground => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// チェック ボタンがオンで、グラデーションが使用される場合に使用する純色を取得します。
        /// <summary>
        public override Color CheckSelectedBackground => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// グリップ (移動ハンドル) のシャドウ効果に使用する色を取得します。
        /// <summary>
        public override Color GripDark => Color.FromArgb(255, 44, 78, 89);
        /// <summary>
        /// グリップ (移動ハンドル) の強調表示効果に使用する色を取得します。
        /// <summary>
        public override Color GripLight => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripDropDownMenu のイメージのマージンで使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color ImageMarginGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripDropDownMenu のイメージのマージンで使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color ImageMarginGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripDropDownMenu のイメージのマージンで使用するグラデーションの中間色を取得します。
        /// <summary>
        public override Color ImageMarginGradientMiddle => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripDropDownMenu に項目が表示される場合にイメージのマージンで使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color ImageMarginRevealedGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripDropDownMenu に項目が表示される場合にイメージのマージンで使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color ImageMarginRevealedGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripDropDownMenu で項目が表示される場合にイメージのマージンで使用するグラデーションの中間色を取得します。
        /// <summary>
        public override Color ImageMarginRevealedGradientMiddle => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// MenuStrip の境界線の色を取得します。
        /// <summary>
        public override Color MenuBorder => Color.FromArgb(255, 111, 195, 223);
        /// <summary>
        /// ToolStripMenuItem で使用する境界線の色を取得します。
        /// <summary>
        public override Color MenuItemBorder => Color.FromArgb(255, 243, 133, 24);
        /// <summary>
        /// 最上位の ToolStripMenuItem が押されている場合に使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color MenuItemPressedGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// 最上位の ToolStripMenuItem が押されている場合に使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color MenuItemPressedGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// 最上位の ToolStripMenuItem が押されている場合に使用するグラデーションの中間色を取得します。
        /// <summary>
        public override Color MenuItemPressedGradientMiddle => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// 最上位の ToolStripMenuItem 以外の ToolStripMenuItem が選択され場合に使用する純色を取得します。
        /// <summary>
        public override Color MenuItemSelected => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripMenuItem が選択された場合に使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color MenuItemSelectedGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripMenuItem が選択された場合に使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color MenuItemSelectedGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// MenuStrip で使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color MenuStripGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// MenuStrip で使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color MenuStripGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripOverflowButton で使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color OverflowButtonGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripOverflowButton で使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color OverflowButtonGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripOverflowButton で使用するグラデーションの中間色を取得します。
        /// <summary>
        public override Color OverflowButtonGradientMiddle => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripContainer で使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color RaftingContainerGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripContainer で使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color RaftingContainerGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripSeparator のシャドウ効果に使用する色を取得します。
        /// <summary>
        public override Color SeparatorDark => Color.FromArgb(255, 44, 78, 89);
        /// <summary>
        /// ToolStripSeparator の強調表示効果に使用する色を取得します。
        /// <summary>
        public override Color SeparatorLight => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// StatusStrip の上端に使用する境界線の色を取得します。
        /// <summary>
        public override Color StatusStripBorder => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// StatusStrip で使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color StatusStripGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// StatusStrip で使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color StatusStripGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// <summary>
        /// ToolStrip の下端に使用する境界線の色を取得します。
        /// <summary>
        public override Color ToolStripBorder => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripContentPanel で使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color ToolStripContentPanelGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripContentPanel で使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color ToolStripContentPanelGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripDropDown の純色の背景色を取得します。
        /// <summary>
        public override Color ToolStripDropDownBackground => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStrip の背景で使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color ToolStripGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStrip の背景で使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color ToolStripGradientEnd => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStrip の背景で使用するグラデーションの中間色を取得します。
        /// <summary>
        public override Color ToolStripGradientMiddle => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripPanel で使用するグラデーションの開始色を取得します。
        /// <summary>
        public override Color ToolStripPanelGradientBegin => Color.FromArgb(255, 0, 0, 0);
        /// <summary>
        /// ToolStripPanel で使用するグラデーションの終了色を取得します。
        /// <summary>
        public override Color ToolStripPanelGradientEnd => Color.FromArgb(255, 0, 0, 0);
    }
}

カラーテーブル以外での描画

カラーテーブルだけでは制御できない箇所を独自に描画します。具体的には下記処理になります。

  • メニューの文字列を白色で描画します。
  • 各ボタンの矢印を白色で描画します。
using System.Drawing;
using System.Windows.Forms;

namespace Test {
    /// <summary>
    /// ハイコントラスト 風レンダラー
    /// </summary>
    public class HighContrastRenderer : ToolStripProfessionalRenderer {

        private Color foreColor;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="foreColor">メニュー文字色。</param>
        /// <param name="colorTable">カラーテーブル。</param>
        public HighContrastRenderer(Color foreColor, ProfessionalColorTable colorTable)
            : base(colorTable) {
            this.foreColor = foreColor;
        }

        /// <summary>
        /// メニューの色設定
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) {
            e.TextColor = this.foreColor;
            base.OnRenderItemText(e);
        }

        /// <summary>
        /// 矢印描画
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e) {
            if (e.Item.Enabled) {
                e.ArrowColor = this.foreColor;
            }
            base.OnRenderArrow(e);
        }
    }
}

適用する方法

メニューバー、ツールバー、ステータスバーのすべてに適用されます。適用する Strip の RenderMode は ToolStripRenderMode.ManagerRenderMode にする必要があります。

ToolStripProfessionalRenderer renderer = new HighContrastRenderer(Color.White, new HighContrastColorTable());
renderer.RoundedEdges = false;
ToolStripManager.Renderer = renderer;
ToolStripManager.VisualStylesEnabled = true;

おわりに

ハイコントラストテーマ以外にダークモードテーマも作成しています。

コメント

タイトルとURLをコピーしました