设计一个c#自定义字体对话框/选择器,过滤掉非真字体
本文关键字:字体 选择器 对话框 过滤 自定义 一个 | 更新日期: 2023-09-27 18:19:03
由于内置字体对话框在选择非True类型字体时返回'Not a True Type Font'异常,我试图使用过滤掉非True类型字体的字体族创建一个自定义字体对话框。
控件工作完美,但我需要这个对话框的大小和样式选择器。我正在发布当前的代码。请帮我添加一个大小和一个样式选择器。它也可能对你有用。
public class FontListBox : ListBox
{
private List<Font> _fonts = new List<Font>();
private Brush _foreBrush;
public FontListBox()
{
DrawMode = DrawMode.OwnerDrawFixed;
ItemHeight = 20;
foreach (FontFamily ff in FontFamily.Families)
{
// determine the first available style, as all fonts don't support all styles
FontStyle? availableStyle = null;
foreach (FontStyle style in Enum.GetValues(typeof(FontStyle)))
{
if (ff.IsStyleAvailable(style))
{
availableStyle = style;
break;
}
}
if (availableStyle.HasValue)
{
Font font = null;
try
{
// do your own Font initialization here
// discard the one you don't like :-)
font = new Font(ff, 12, availableStyle.Value);
}
catch
{
}
if (font != null)
{
_fonts.Add(font);
Items.Add(font);
}
}
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (_fonts != null)
{
foreach (Font font in _fonts)
{
font.Dispose();
}
_fonts = null;
}
if (_foreBrush != null)
{
_foreBrush.Dispose();
_foreBrush = null;
}
}
public override Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
if (_foreBrush != null)
{
_foreBrush.Dispose();
}
_foreBrush = null;
}
}
private Brush ForeBrush
{
get
{
if (_foreBrush == null)
{
_foreBrush = new SolidBrush(ForeColor);
}
return _foreBrush;
}
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
if (e.Index < 0)
return;
e.DrawBackground();
e.DrawFocusRectangle();
Rectangle bounds = e.Bounds;
Font font = (Font)Items[e.Index];
e.Graphics.DrawString(font.Name, font, ForeBrush, bounds.Left, bounds.Top);
}
}
public partial class MyFontDialog : Form
{
private FontListBox _fontListBox;
public MyFontDialog()
{
InitializeComponent();
_fontListBox = new FontListBox();
_fontListBox.Dock = DockStyle.Fill;
Controls.Add(_fontListBox);
}
}
我已经在sourceforge https://sourceforge.net/p/newfontpicker/上托管了这个项目
你可以这样修改MyFontDialog:
public partial class MyFontDialog : Form
{
private FontListBox _fontListBox;
private ListBox _fontSizeListBox;
public MyFontDialog()
{
//InitializeComponent();
_fontListBox = new FontListBox();
_fontListBox.SelectedIndexChanged += OnfontListBoxSelectedIndexChanged;
_fontListBox.Size = new Size(200, Height);
Controls.Add(_fontListBox);
_fontSizeListBox = new ListBox();
_fontSizeListBox.Location = new Point(_fontListBox.Width, 0);
Controls.Add(_fontSizeListBox);
}
private void OnfontListBoxSelectedIndexChanged(object sender, EventArgs e)
{
_fontSizeListBox.Items.Clear();
Font font = _fontListBox.SelectedItem as Font;
if (font != null)
{
foreach (FontStyle style in Enum.GetValues(typeof(FontStyle)))
{
if (font.FontFamily.IsStyleAvailable(style))
{
_fontSizeListBox.Items.Add(style);
}
}
}
}
}
它将在字体列表框旁边创建一个列表框,其中包含可用字体样式列表。至于大小选择,您可以简单地添加一个列表框,其大小为:8、9、10、11、12、14、16、18、20、22、24、26、28、36、48和72,就像标准FontDialog一样,因为我们处理的是真正的字体。
http://www.developerfusion.com/code/254/determine-if-a-font-is-truetype/有一些VB代码来确定字体是否是TT字体。它真正做的就是调用一些Win32 API函数并检查结果。
可能有一些字体看起来是TT,但实际上不是,甚至当使用Win32 API检查时(FontDialog可能无论如何都在做)。如果Win32不能解决您的问题,那么找出字体是否无效的唯一方法可能是检查异常。
OK, Umar,你应该试试:
1)使用FontFamily。IsStyleAvailable'避免/最小化捕获异常的需要——从而错过了一些可用的字体。2)玩一点图像。MeasureString为每个单独的字体设置一个大小,它看起来最好,并且会让你的列等高…
Happy trying:)
Jens,丹麦。