single.php

C# WinFormsのコンテキストメニューにFontIconを適用する

C#のWinFormsプロジェクトで、メニューのアイコン表示に、フォントアイコンを使う方法について備忘録的に投稿します。

フォントアイコンを画像にする

WinUIなどXamlを利用するプロジェクトの場合は、FontIconクラスが用意されています。

しかし、WinFormsプロジェクトの場合は、そのままでは使えないので指定されたフォントを画像にする必要があります。

具体的には、こんな感じになります。

private List<Bitmap> _contextmenuIcons = new();

private Bitmap SetFluentIcon(string unicodeGlyph, int size = 16, Color? iconColor = null)
{
    Bitmap bmp = new Bitmap(size, size);

    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
        using (System.Drawing.Font font = new System.Drawing.Font("Segoe Fluent Icons", size, FontStyle.Regular, GraphicsUnit.Pixel))
        {
            Color color = iconColor ?? SystemColors.ControlText;
            using (Brush brush = new SolidBrush(color))
            {
                StringFormat sf = new StringFormat
                {
                    Alignment = StringAlignment.Center,
                    LineAlignment = StringAlignment.Center
                };
                RectangleF rect = new RectangleF(0, 0, size, size);
                g.DrawString(unicodeGlyph, font, brush, rect, sf);
            }
        }
    }
    _contextmenuIcons.Add(bmp);
    return bmp;
}

private void SetupContextMenuIcons()
{
    foreach (var bmp in _contextmenuIcons)
    {
        bmp.Dispose();
    }
    _contextmenuIcons.Clear();
    SetFluentIcon("\uE72C", 18, UIColorTypeish.Foreground);
    SetFluentIcon("\uE73E", 18, UIColorTypeish.Foreground);
    SetFluentIcon("\uF3B1", 18, UIColorTypeish.Foreground);
}

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        foreach (var bmp in _contextmenuIcons)
        {
            bmp.Dispose();
        }
    }
    base.Dispose(disposing);
}

画像の受け渡しを行うのでメモリリークを防止するために、作成した画像は変数として保持しておいて、アプリ終了時にDispose処理を追加しています。

実際に呼び出す場合は、アプリのコンストラクター部分で[SetupContextMenuIcons]を呼び出してから、メニューに画像として設定します。

var menu = new ContextMenuStrip();
menu.Items.Add("設定再読み込み", _contextmenuIcons[0], (_, _) => ReloadConfig());
menu.Items.Add("-");
menu.Items.Add(startUpText, _contextmenuIcons[1], (s, _) => SetWinStartUp(s));
menu.Items.Add("-");
menu.Items.Add("終了", _contextmenuIcons[2], (_, _) => Exit());

実行すると、ポップアップメニューにアイコンが追加されます。

まとめ

今回は、C#のWinFormsプロジェクトで、メニューのアイコン表示にフォントアイコンを使う方法について書きました。

WinFormsプロジェクトの場合、WinUI3プロジェクトなどで利用可能なFontIconクラスは使えないのでフォントを画像化してメニューに設定します。

WinFormsプロジェクトでメニューのアイコンにフォントを使いたい人の参考になれば幸いです。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です