在Windows Forms应用程序中更改菜单字体,.net3.5。

3

我的表单上有一个菜单,定义如下:

private System.Windows.Forms.MainMenu mainMenu1;

//Then

private void InitializeComponent()
{
 this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);
 this.Menu = this.mainMenu1;
}

我设置了整个表单的字体,但菜单项仍然忽略它。如何使菜单项的字体变大?我找不到菜单或菜单项的字体属性....

1个回答

5
如果您正在使用MainMenu,则无法直接执行此操作。您应该使用MenuStrip

如果您绝对必须使用MainMenu,则必须将MenuItemOwnerDraw属性设置为true,并覆盖/实现DrawItemMeasureItem事件,以便您可以手动绘制它。


这是一个非常基本的自定义菜单项类; 它还不完整或完全功能,但它应该可以帮助您入门:

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

class CustomMenuItem : MenuItem
{
    private Font _font;
    public Font Font
    {
        get
        {
            return _font;
        }
        set
        {
            _font = value;
        }
    }

    public CustomMenuItem()
    {
        this.OwnerDraw = true;
        this.Font = SystemFonts.DefaultFont;
    }

    public CustomMenuItem(string text)
        : this()
    {
        this.Text = text;
    }

    // ... Add other constructor overrides as needed

    protected override void OnMeasureItem(MeasureItemEventArgs e)
    {
        // I would've used a Graphics.FromHwnd(this.Handle) here instead,
        // but for some reason I always get an OutOfMemoryException,
        // so I've fallen back to TextRenderer

        var size = TextRenderer.MeasureText(this.Text, this.Font);
        e.ItemWidth = (int)size.Width;
        e.ItemHeight = (int)size.Height;
    }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        e.DrawBackground();
        e.Graphics.DrawString(this.Text, this.Font, Brushes.Blue, e.Bounds);
    }
}

以下是3层测试的使用方法:
MainMenu mainMenu = new MainMenu();
MenuItem menuFile = new CustomMenuItem("File");
MenuItem menuOpen = new CustomMenuItem("Open");
MenuItem menuNew = new CustomMenuItem("New");

public MenuTestForm()
{
    InitializeComponent();

    this.Menu = mainMenu;
    mainMenu.MenuItems.Add(menuFile);
    menuFile.MenuItems.Add(menuOpen);
    menuOpen.MenuItems.Add(menuNew);
}

输出结果:

输入图像描述


谢谢,这需要为MainMenu中的每个MenuItemm都完成吗? - sarsnake
我认为你需要为每个 MenuItem 注册事件,但不一定需要为每个事件编写不同的方法。更好的方法是从 MenuItem 派生出自己的类,给它一个 Font 属性,并覆盖其中的两个事件。 - Jeff
说得太早了。我有几个是MainMenu的子项,在将字体设置为更大后,它们不再显示。我怀疑我需要覆盖MeasureItem。在事件里我应该放什么? - sarsnake
实际上,即使绑定了事件到每个菜单项,也无法正常工作,因为customItem.Text(其中MenuItem customItem = (MenuItem)sender;)始终输出我分配给顶部项目的文本,即使子菜单项已绘制。总共有3级菜单。没有更简单的方法吗?我真的没有时间重写整个菜单部分。这只是一种样式更改,应该非常简单。 - sarsnake
更新了我的回答。当涉及使用过时的控件时,如果需要自定义行为,则没有免费的午餐:P - Jeff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接