【问题标题】:Designing a Custom Font Dialog/Selector for C# that filters out non true type fonts为 C# 设计一个自定义字体对话框/选择器,过滤掉非真字体
【发布时间】:2012-01-28 11:07:24
【问题描述】:

由于内置字体对话框在选择非 True Type 字体时返回“Not a True Type Font”异常,我正在尝试使用过滤掉非 True Type 字体的字体系列创建自定义字体对话框。

控件运行良好,但我需要此对话框的大小和样式选择器。我正在发布当前代码。请帮我添加尺寸和样式选择器。它也可能对您有用。

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/ 主持了这个项目

【问题讨论】:

标签: c# .net winforms fonts dialog


【解决方案1】:

http://www.developerfusion.com/code/254/determine-if-a-font-is-truetype/ 有一些 VB 代码来确定字体是否为 TT 字体。它真正做的只是调用一些 Win32 API 函数并检查结果。

可能有一些字体看起来是 TT,但实际上不是,即使使用 Win32 API 进行检查(FontDialog 无论如何都可能正在这样做)。如果 Win32 不能解决您的问题,那么找出字体是否无效的唯一方法可能是检查异常。

【讨论】:

    【解决方案2】:

    您可以像这样修改 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 一样,因为我们处理的是真字体。

    【讨论】:

      【解决方案3】:

      好的,奥马尔, 你应该试试:

      1) 使用“FontFamily.IsStyleAvailable”来避免/最小化捕获异常的需要—— 从而错过了一些可用的字体。 2) 玩一点 Graphics.MeasureString 为每个单独的字体设置一个看起来最好的大小,并且会让你得到相同高度的列...

      尝试愉快:)

      丹麦延斯。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-22
        • 2018-01-26
        • 2021-11-27
        • 2014-04-08
        • 2022-08-16
        • 2012-10-14
        • 2012-12-11
        • 2010-09-21
        相关资源
        最近更新 更多