65.9K
CodeProject 正在变化。 阅读更多。
Home

FontComboBox - 用于 .NET 的字体列表组合框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (17投票s)

2002 年 8 月 5 日

Ms-PL

2分钟阅读

viewsIcon

260872

downloadIcon

8844

一个完全由所有者绘制的 ComboBox 派生类,用于枚举和选择字体

概述

FontComboBox 是一个派生自 ComboBox 的类,它被封装到一个 .NET 控件库中。 它将下拉显示您机器上安装的所有 TrueType 字体列表。 FontComboBox 有两种样式 - 一种是每个字体名称都使用其字体呈现,另一种是每个字体名称都使用默认字体显示,然后使用选定的字体显示一些文本。

在您的项目中进行使用

将控件添加到您的工具箱

右键单击您的工具箱,然后选择“自定义工具箱”选项。 浏览到 *FontCombo.dll* 文件,并将其添加到您的工具箱。

初始化字体组合框

有一个名为 Populate 的公共方法,您需要在每个 FontComboBox 对象上调用它。

public Form1()
{
    InitializeComponent();
    fontComboBox1.Populate(false); //Simple
    fontComboBox2.Populate(true); //Elaborate
}

检索当前选定的字体

您需要做的就是使用 Text 属性。

private void button1_Click(object sender, System.EventArgs e)
{
    textBox1.Font = new Font(fontComboBox1.Text,10);
    textBox2.Font = new Font(fontComboBox2.Text,10);
}

类参考

您只有一个公共方法可以使用 [除了通过基类提供的任何公共方法或属性]

Populate

public void Populate(bool b)

这将使用您机器上安装的所有 TrueType 字体填充组合框。 bool 参数确定组合框的样式。 调用 Populate(false) 以获得简单的样式字体组合框,并调用 Populate(true) 以获得精细的样式字体组合框。 在简单样式中,每个字体名称都使用其字体呈现。 在精细样式中,每个字体名称都使用默认字体呈现,但一些示例文本使用特定字体呈现。

技术细节

基本上这是一个所有者绘制的组合框,并将 DrawMode 设置为 DrawMode.OwnerDrawVariable。 我们需要做的第一件事显然是枚举机器上的 TrueType 字体。 这是通过以下方式完成的 [部分代码片段,完整代码请参考源代码]

foreach (FontFamily ff in FontFamily.Families)
{
    if(ff.IsStyleAvailable(FontStyle.Regular))
        Items.Add(ff.Name);                                             
}

现在我们需要覆盖 OnMeasureItem。 当需要绘制所有者绘制的组合框项目时,将调用此方法,并在 OnDrawItem 之前调用。 在这里,我们可以指定宽度、高度等。 我们使用 Graphics.MeasureString 来获取特定字体中呈现文本的文本范围。

protected override void OnMeasureItem(
                        MeasureItemEventArgs e)
{   
    ...

    Graphics g = CreateGraphics();
    e.ItemHeight = (int)g.MeasureString(fontstring, 
        new Font(fontstring,10)).Height;
    w = (int)g.MeasureString(fontstring, 
        new Font(fontstring,10)).Width;
    if(both)
    {
        int h1 = (int)g.MeasureString(samplestr, 
            new Font(fontstring,10)).Height;
        int h2 = (int)g.MeasureString(
            Items[e.Index].ToString(), 
            new Font("Arial",10)).Height;
        int w1 = (int)g.MeasureString(samplestr, 
            new Font(fontstring,10)).Width;
        int w2 = (int)g.MeasureString(
            Items[e.Index].ToString(), 
            new Font("Arial",10)).Width;

        ...
    }

    ...
}

现在显然我们处理 OnDrawItem,我们在那里做我们实际的绘图工作。

protected override void OnDrawItem(
                    DrawItemEventArgs e)
{   
    ...

    string fontstring = Items[e.Index].ToString();
    nfont = new Font(fontstring,10);
    Font afont = new Font("Arial",10);

    if(both)
    {
        Graphics g = CreateGraphics();
        int w = (int)g.MeasureString(fontstring, 
            afont).Width;

        if((e.State & DrawItemState.Focus)==0)
        {
            //Normal item
            e.Graphics.FillRectangle(new SolidBrush(
                SystemColors.Window),
                e.Bounds.X+ttimg.Width,e.Bounds.Y,
                e.Bounds.Width,e.Bounds.Height);
            e.Graphics.DrawString(fontstring,afont,
                new SolidBrush(SystemColors.WindowText),
                e.Bounds.X+ttimg.Width*2,e.Bounds.Y);   
            e.Graphics.DrawString(samplestr,nfont,
                new SolidBrush(SystemColors.WindowText),
                e.Bounds.X+w+ttimg.Width*2,e.Bounds.Y); 
        }
        else
        {
            //Highlighted item

            ...
        }   
    }
    else
    {

        if((e.State & DrawItemState.Focus)==0)
        {
            //Normal item
            e.Graphics.FillRectangle(new SolidBrush(
                SystemColors.Window),
                e.Bounds.X+ttimg.Width,e.Bounds.Y,
                e.Bounds.Width,e.Bounds.Height);
            e.Graphics.DrawString(fontstring,nfont,
                new SolidBrush(SystemColors.WindowText),
                e.Bounds.X+ttimg.Width*2,e.Bounds.Y);

        }
        else
        {
            //Highlighted item

            ...
        }           

    }

    ...
}

致谢

  • Chris Losinger - 我编写这个类部分是由于我当前项目的要求,部分是因为我受到 Chris Losinger 的 MFC 字体组合框的启发。
  • Senkwe Chanda - Senkwe 制作所有者绘制组合框的出色初学者文章对我帮助很大。
  • Nnamdi Onyeyiri - 当我编写这个类时,Nnamdi 和我一起在 Sonork 工作,我感谢他使用系统字体颜色进行高亮的提示。 最初我使用的是硬编码的颜色。

链接

© . All rights reserved.