Разработка настраиваемого диалогового окна / селектора шрифтов для C #, отфильтровывающего шрифты не истинного типа - PullRequest
8 голосов
/ 27 декабря 2011

Поскольку встроенный диалог шрифтов возвращает исключение «Не истинный тип шрифта» при выборе шрифта не истинного типа, я пытаюсь создать собственный диалог шрифтов с использованием семейств шрифтов, которые отфильтровывают шрифты не истинного типа.*

Элемент управления работает отлично, но мне нужны селекторы размера и стиля для этого диалога.Я публикую текущий код.Пожалуйста, помогите мне добавить размер и стиль выбора к этому.Это также может быть полезно для вас.

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/

Ответы [ 3 ]

1 голос
/ 05 января 2012

Вы можете изменить 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, так как мы имеем дело со шрифтами истинного типа.

0 голосов
/ 08 декабря 2013

ОК, Умар, Вы должны попробовать:

1) Использование FontFamily.IsStyleAvailable, чтобы избежать / минимизировать необходимость перехвата исключений - и, таким образом, упустить некоторые доступные шрифты.2) Немного поиграйте с Graphics.MeasureString, чтобы установить размер для каждого отдельного шрифта, который выглядит лучше всего, и вы получите столбцы одинаковой высоты ...

Счастливых попыток:)

Йенс, Дания.

0 голосов
/ 04 января 2012

http://www.developerfusion.com/code/254/determine-if-a-font-is-truetype/ имеет некоторый VB-код, чтобы определить, является ли шрифт шрифтом TT. Все, что он на самом деле делает, - это вызывает некоторые функции Win32 API и анализирует результаты.

Могут быть некоторые шрифты, которые выглядят как TT, но это не так, даже если они проверяются с помощью Win32 API (что FontDialog, вероятно, делает в любом случае). Если Win32 не решает вашу проблему, то, вероятно, единственный способ выяснить, является ли шрифт недействительным, это проверить исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...