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






4.93/5 (17投票s)
一个完全由所有者绘制的 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 工作,我感谢他使用系统字体颜色进行高亮的提示。 最初我使用的是硬编码的颜色。