【问题标题】:Changing the font for menu in the Windows Forms application, .net3.5更改 Windows 窗体应用程序中菜单的字体,.net3.5
【发布时间】:2012-10-01 22:07:48
【问题描述】:

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

private System.Windows.Forms.MainMenu mainMenu1;

//Then

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

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

【问题讨论】:

    标签: c# winforms .net-3.5 fonts


    【解决方案1】:

    如果您使用的是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-deep 测试用法:

    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 执行此操作?
    • 我认为您必须为每个MenuItem 注册事件,但您不一定需要为每个事件编写不同的方法。更好的方法是从MenuItem 派生您自己的类,给它一个Font 属性并覆盖其中的两个事件。
    • 说得太早了。我有几个 MainMenu 的子项,在将字体设置为更大后,它们不再显示。我怀疑我毕竟需要覆盖 MeasureItem 。我在活动中放了什么?
    • 实际上,即使在将事件绑定到每个 MenuItem 之后也不起作用,因为 customItem.Text (其中 MenuItem customItem = (MenuItem)sender;)总是输出我分配给最顶层项目的文本即使绘制了子菜单项。我总共有 3 级菜单。没有更简单的方法吗?我真的不能花时间重写整个菜单位。这只是一种风格变化,应该相当简单。
    • 更新了我的答案。在使用过时的控件时,当您需要自定义行为时,没有免费的午餐:P
    猜你喜欢
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2014-03-16
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多